bolt-table 0.1.26 → 0.1.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +780 -1
- package/dist/index.d.mts +49 -9
- package/dist/index.d.ts +49 -9
- package/dist/index.js +691 -124
- package/dist/index.mjs +698 -125
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -124,6 +124,18 @@ var EyeOffIcon = ({ style, className }) => /* @__PURE__ */ (0, import_jsx_runtim
|
|
|
124
124
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M6.61 6.61A13.526 13.526 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61" }),
|
|
125
125
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "2", x2: "22", y1: "2", y2: "22" })
|
|
126
126
|
] });
|
|
127
|
+
var SearchIcon = ({ style, className }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { ...svgBase, style, className, children: [
|
|
128
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "11", cy: "11", r: "8" }),
|
|
129
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m21 21-4.3-4.3" })
|
|
130
|
+
] });
|
|
131
|
+
var ColumnsIcon = ({ style, className }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { ...svgBase, style, className, children: [
|
|
132
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", ry: "2" }),
|
|
133
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "12", x2: "12", y1: "3", y2: "21" })
|
|
134
|
+
] });
|
|
135
|
+
var XIcon = ({ style, className }) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { ...svgBase, style, className, children: [
|
|
136
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M18 6 6 18" }),
|
|
137
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m6 6 12 12" })
|
|
138
|
+
] });
|
|
127
139
|
|
|
128
140
|
// src/DraggableHeader.tsx
|
|
129
141
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
@@ -823,7 +835,15 @@ var EditableCell = ({
|
|
|
823
835
|
onEdit(coerced, record, column.dataIndex, rowIndex);
|
|
824
836
|
}
|
|
825
837
|
onEditComplete();
|
|
826
|
-
}, [
|
|
838
|
+
}, [
|
|
839
|
+
draft,
|
|
840
|
+
value,
|
|
841
|
+
column.dataIndex,
|
|
842
|
+
record,
|
|
843
|
+
rowIndex,
|
|
844
|
+
onEdit,
|
|
845
|
+
onEditComplete
|
|
846
|
+
]);
|
|
827
847
|
const cancel = (0, import_react3.useCallback)(() => {
|
|
828
848
|
onEditComplete();
|
|
829
849
|
}, [onEditComplete]);
|
|
@@ -925,7 +945,11 @@ var Cell = import_react3.default.memo(
|
|
|
925
945
|
rowSelection.onSelect?.(record, true, [record], e.nativeEvent);
|
|
926
946
|
rowSelection.onChange?.([rawKey], [record], { type: "single" });
|
|
927
947
|
},
|
|
928
|
-
style: {
|
|
948
|
+
style: {
|
|
949
|
+
cursor: "pointer",
|
|
950
|
+
accentColor,
|
|
951
|
+
backgroundColor: "#94A3B8"
|
|
952
|
+
}
|
|
929
953
|
}
|
|
930
954
|
) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
931
955
|
"input",
|
|
@@ -951,7 +975,11 @@ var Cell = import_react3.default.memo(
|
|
|
951
975
|
type: "multiple"
|
|
952
976
|
});
|
|
953
977
|
},
|
|
954
|
-
style: {
|
|
978
|
+
style: {
|
|
979
|
+
cursor: "pointer",
|
|
980
|
+
accentColor,
|
|
981
|
+
backgroundColor: "#94A3B8"
|
|
982
|
+
}
|
|
955
983
|
}
|
|
956
984
|
);
|
|
957
985
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
@@ -1087,6 +1115,33 @@ var MeasuredExpandedRow = import_react3.default.memo(
|
|
|
1087
1115
|
}
|
|
1088
1116
|
);
|
|
1089
1117
|
MeasuredExpandedRow.displayName = "MeasuredExpandedRow";
|
|
1118
|
+
var DynamicRowMeasurer = import_react3.default.memo(
|
|
1119
|
+
({
|
|
1120
|
+
index,
|
|
1121
|
+
onHeightChange,
|
|
1122
|
+
children
|
|
1123
|
+
}) => {
|
|
1124
|
+
const ref = (0, import_react3.useRef)(null);
|
|
1125
|
+
const onHeightChangeRef = (0, import_react3.useRef)(onHeightChange);
|
|
1126
|
+
(0, import_react3.useEffect)(() => {
|
|
1127
|
+
onHeightChangeRef.current = onHeightChange;
|
|
1128
|
+
}, [onHeightChange]);
|
|
1129
|
+
(0, import_react3.useEffect)(() => {
|
|
1130
|
+
const el = ref.current;
|
|
1131
|
+
if (!el) return;
|
|
1132
|
+
const observer = new ResizeObserver((entries) => {
|
|
1133
|
+
const height = entries[0]?.borderBoxSize?.[0]?.blockSize;
|
|
1134
|
+
if (height != null && height > 0) {
|
|
1135
|
+
onHeightChangeRef.current(index, Math.ceil(height));
|
|
1136
|
+
}
|
|
1137
|
+
});
|
|
1138
|
+
observer.observe(el);
|
|
1139
|
+
return () => observer.disconnect();
|
|
1140
|
+
}, [index]);
|
|
1141
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { ref, children });
|
|
1142
|
+
}
|
|
1143
|
+
);
|
|
1144
|
+
DynamicRowMeasurer.displayName = "DynamicRowMeasurer";
|
|
1090
1145
|
var TableBody = ({
|
|
1091
1146
|
data,
|
|
1092
1147
|
orderedColumns,
|
|
@@ -1116,11 +1171,17 @@ var TableBody = ({
|
|
|
1116
1171
|
bodyGridRow = 2,
|
|
1117
1172
|
onEdit,
|
|
1118
1173
|
editingCell,
|
|
1119
|
-
onEditComplete
|
|
1174
|
+
onEditComplete,
|
|
1175
|
+
enableDynamicRowHeight = false,
|
|
1176
|
+
onRowHeightChange,
|
|
1177
|
+
columnGridIndexMap
|
|
1120
1178
|
}) => {
|
|
1121
1179
|
const virtualItems = rowVirtualizer.getVirtualItems();
|
|
1122
1180
|
const totalSize = rowVirtualizer.getTotalSize();
|
|
1123
|
-
const selectedKeySet = (0, import_react3.useMemo)(
|
|
1181
|
+
const selectedKeySet = (0, import_react3.useMemo)(
|
|
1182
|
+
() => new Set(normalizedSelectedKeys),
|
|
1183
|
+
[normalizedSelectedKeys]
|
|
1184
|
+
);
|
|
1124
1185
|
const safeData = data ?? [];
|
|
1125
1186
|
const safeColumns = orderedColumns ?? [];
|
|
1126
1187
|
const allDataForSelection = (0, import_react3.useMemo)(() => {
|
|
@@ -1136,8 +1197,9 @@ var TableBody = ({
|
|
|
1136
1197
|
let zIndex = 0;
|
|
1137
1198
|
if (col.key === "__select__" || col.key === "__expand__") zIndex = 11;
|
|
1138
1199
|
else if (isPinned) zIndex = 2;
|
|
1200
|
+
const gridCol = columnGridIndexMap?.get(col.key) ?? colIndex + 1;
|
|
1139
1201
|
const style = {
|
|
1140
|
-
gridColumn:
|
|
1202
|
+
gridColumn: gridCol,
|
|
1141
1203
|
gridRow: bodyGridRow,
|
|
1142
1204
|
height: `${totalSize}px`,
|
|
1143
1205
|
position: isPinned ? "sticky" : "relative",
|
|
@@ -1152,7 +1214,7 @@ var TableBody = ({
|
|
|
1152
1214
|
}
|
|
1153
1215
|
return { key: col.key, style, isPinned };
|
|
1154
1216
|
});
|
|
1155
|
-
}, [safeColumns, columnOffsets, totalSize, styles, bodyGridRow]);
|
|
1217
|
+
}, [safeColumns, columnOffsets, totalSize, styles, bodyGridRow, columnGridIndexMap]);
|
|
1156
1218
|
if (safeData.length === 0 || safeColumns.length === 0) return null;
|
|
1157
1219
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
1158
1220
|
columnStyles.map((colStyle, colIndex) => {
|
|
@@ -1203,15 +1265,58 @@ var TableBody = ({
|
|
|
1203
1265
|
top: `${virtualRow.start}px`,
|
|
1204
1266
|
left: 0,
|
|
1205
1267
|
right: 0,
|
|
1206
|
-
height: `${virtualRow.size}px`,
|
|
1207
|
-
|
|
1268
|
+
height: enableDynamicRowHeight ? void 0 : `${virtualRow.size}px`,
|
|
1269
|
+
minHeight: enableDynamicRowHeight ? `${rowHeight}px` : void 0
|
|
1208
1270
|
},
|
|
1209
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1271
|
+
children: enableDynamicRowHeight && onRowHeightChange && colIndex === 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1272
|
+
DynamicRowMeasurer,
|
|
1273
|
+
{
|
|
1274
|
+
index: virtualRow.index,
|
|
1275
|
+
onHeightChange: onRowHeightChange,
|
|
1276
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1277
|
+
"div",
|
|
1278
|
+
{
|
|
1279
|
+
style: {
|
|
1280
|
+
minHeight: `${rowHeight}px`,
|
|
1281
|
+
position: "relative",
|
|
1282
|
+
...rowSty
|
|
1283
|
+
},
|
|
1284
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1285
|
+
Cell,
|
|
1286
|
+
{
|
|
1287
|
+
value: cellValue,
|
|
1288
|
+
record: row,
|
|
1289
|
+
column: col,
|
|
1290
|
+
rowIndex: virtualRow.index,
|
|
1291
|
+
classNames,
|
|
1292
|
+
styles,
|
|
1293
|
+
isSelected,
|
|
1294
|
+
isExpanded,
|
|
1295
|
+
rowSelection,
|
|
1296
|
+
normalizedSelectedKeys,
|
|
1297
|
+
rowKey,
|
|
1298
|
+
allData: allDataForSelection,
|
|
1299
|
+
getRowKey,
|
|
1300
|
+
getRawRowKey,
|
|
1301
|
+
accentColor,
|
|
1302
|
+
isLoading: isRowShimmer,
|
|
1303
|
+
recordFingerprint,
|
|
1304
|
+
onEdit,
|
|
1305
|
+
isEditing: editingCell?.rowKey === rowKey && editingCell?.columnKey === col.key,
|
|
1306
|
+
onEditComplete
|
|
1307
|
+
}
|
|
1308
|
+
)
|
|
1309
|
+
}
|
|
1310
|
+
)
|
|
1311
|
+
}
|
|
1312
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1210
1313
|
"div",
|
|
1211
1314
|
{
|
|
1212
1315
|
style: {
|
|
1213
|
-
height: `${rowHeight}px`,
|
|
1214
|
-
|
|
1316
|
+
height: enableDynamicRowHeight ? void 0 : `${rowHeight}px`,
|
|
1317
|
+
minHeight: enableDynamicRowHeight ? `${rowHeight}px` : void 0,
|
|
1318
|
+
position: "relative",
|
|
1319
|
+
...rowSty
|
|
1215
1320
|
},
|
|
1216
1321
|
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1217
1322
|
Cell,
|
|
@@ -1266,7 +1371,12 @@ var TableBody = ({
|
|
|
1266
1371
|
if (!(resolvedExpandedKeys?.has(rk) ?? false)) return null;
|
|
1267
1372
|
let expandedRenderResult = null;
|
|
1268
1373
|
try {
|
|
1269
|
-
expandedRenderResult = expandable.expandedRowRender(
|
|
1374
|
+
expandedRenderResult = expandable.expandedRowRender(
|
|
1375
|
+
row,
|
|
1376
|
+
virtualRow.index,
|
|
1377
|
+
0,
|
|
1378
|
+
true
|
|
1379
|
+
);
|
|
1270
1380
|
} catch {
|
|
1271
1381
|
}
|
|
1272
1382
|
const expandedContent = /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
@@ -1634,7 +1744,16 @@ function BoltTable({
|
|
|
1634
1744
|
onCopy,
|
|
1635
1745
|
keepPinnedRowsAcrossPages,
|
|
1636
1746
|
onEdit,
|
|
1637
|
-
onRowClick
|
|
1747
|
+
onRowClick,
|
|
1748
|
+
enableColumnVirtualization = false,
|
|
1749
|
+
enableDynamicRowHeight = false,
|
|
1750
|
+
columnPersistence = false,
|
|
1751
|
+
showColumnSettings = true,
|
|
1752
|
+
hideGlobalSearch = false,
|
|
1753
|
+
globalSearchValue,
|
|
1754
|
+
onGlobalSearchChange,
|
|
1755
|
+
toolbarContent,
|
|
1756
|
+
columnSettingsLabel
|
|
1638
1757
|
}) {
|
|
1639
1758
|
const data = (0, import_react4.useMemo)(() => {
|
|
1640
1759
|
if (!Array.isArray(rawData)) return STABLE_EMPTY_DATA;
|
|
@@ -1642,7 +1761,8 @@ function BoltTable({
|
|
|
1642
1761
|
return filtered.length > 0 ? filtered : STABLE_EMPTY_DATA;
|
|
1643
1762
|
}, [rawData]);
|
|
1644
1763
|
const initialColumns = (0, import_react4.useMemo)(() => {
|
|
1645
|
-
if (!Array.isArray(rawInitialColumns))
|
|
1764
|
+
if (!Array.isArray(rawInitialColumns))
|
|
1765
|
+
return STABLE_EMPTY_COLS;
|
|
1646
1766
|
const safe = rawInitialColumns.filter(
|
|
1647
1767
|
(col) => col != null && typeof col.key === "string"
|
|
1648
1768
|
);
|
|
@@ -1707,6 +1827,106 @@ function BoltTable({
|
|
|
1707
1827
|
() => /* @__PURE__ */ new Map()
|
|
1708
1828
|
);
|
|
1709
1829
|
const manuallyResizedRef = (0, import_react4.useRef)(/* @__PURE__ */ new Set());
|
|
1830
|
+
const persistenceAppliedRef = (0, import_react4.useRef)(false);
|
|
1831
|
+
import_react4.default.useEffect(() => {
|
|
1832
|
+
if (!columnPersistence || persistenceAppliedRef.current) return;
|
|
1833
|
+
persistenceAppliedRef.current = true;
|
|
1834
|
+
const {
|
|
1835
|
+
storageKey,
|
|
1836
|
+
persistOrder = true,
|
|
1837
|
+
persistWidths = true,
|
|
1838
|
+
persistVisibility = true,
|
|
1839
|
+
persistPinned = true
|
|
1840
|
+
} = columnPersistence;
|
|
1841
|
+
try {
|
|
1842
|
+
const raw = localStorage.getItem(`bt_${storageKey}`);
|
|
1843
|
+
if (!raw) return;
|
|
1844
|
+
const saved = JSON.parse(raw);
|
|
1845
|
+
if (persistOrder && saved.order) {
|
|
1846
|
+
setColumnOrder(saved.order);
|
|
1847
|
+
}
|
|
1848
|
+
if (persistWidths && saved.widths) {
|
|
1849
|
+
setColumnWidths(
|
|
1850
|
+
new Map(Object.entries(saved.widths).map(([k, v]) => [k, Number(v)]))
|
|
1851
|
+
);
|
|
1852
|
+
}
|
|
1853
|
+
if (persistVisibility && saved.hidden || persistPinned && saved.pinned) {
|
|
1854
|
+
setColumns(
|
|
1855
|
+
(prev) => prev.map((col) => {
|
|
1856
|
+
let updated = col;
|
|
1857
|
+
if (persistVisibility && saved.hidden && col.key in saved.hidden) {
|
|
1858
|
+
updated = { ...updated, hidden: saved.hidden[col.key] };
|
|
1859
|
+
}
|
|
1860
|
+
if (persistPinned && saved.pinned && col.key in saved.pinned) {
|
|
1861
|
+
updated = { ...updated, pinned: saved.pinned[col.key] };
|
|
1862
|
+
}
|
|
1863
|
+
return updated;
|
|
1864
|
+
})
|
|
1865
|
+
);
|
|
1866
|
+
}
|
|
1867
|
+
} catch {
|
|
1868
|
+
}
|
|
1869
|
+
}, [columnPersistence]);
|
|
1870
|
+
const persistColumnsToStorage = (0, import_react4.useCallback)(() => {
|
|
1871
|
+
if (!columnPersistence) return;
|
|
1872
|
+
const {
|
|
1873
|
+
storageKey,
|
|
1874
|
+
persistOrder = true,
|
|
1875
|
+
persistWidths = true,
|
|
1876
|
+
persistVisibility = true,
|
|
1877
|
+
persistPinned = true
|
|
1878
|
+
} = columnPersistence;
|
|
1879
|
+
try {
|
|
1880
|
+
const saved = {};
|
|
1881
|
+
if (persistOrder) saved.order = columnOrder;
|
|
1882
|
+
if (persistWidths) {
|
|
1883
|
+
const widths = {};
|
|
1884
|
+
columnWidths.forEach((v, k) => {
|
|
1885
|
+
widths[k] = v;
|
|
1886
|
+
});
|
|
1887
|
+
saved.widths = widths;
|
|
1888
|
+
}
|
|
1889
|
+
if (persistVisibility) {
|
|
1890
|
+
const hidden = {};
|
|
1891
|
+
columns.forEach((c) => {
|
|
1892
|
+
if (c.hidden) hidden[c.key] = true;
|
|
1893
|
+
});
|
|
1894
|
+
saved.hidden = hidden;
|
|
1895
|
+
}
|
|
1896
|
+
if (persistPinned) {
|
|
1897
|
+
const pinned = {};
|
|
1898
|
+
columns.forEach((c) => {
|
|
1899
|
+
if (c.pinned) pinned[c.key] = c.pinned;
|
|
1900
|
+
});
|
|
1901
|
+
saved.pinned = pinned;
|
|
1902
|
+
}
|
|
1903
|
+
localStorage.setItem(`bt_${storageKey}`, JSON.stringify(saved));
|
|
1904
|
+
} catch {
|
|
1905
|
+
}
|
|
1906
|
+
}, [columnPersistence, columnOrder, columnWidths, columns]);
|
|
1907
|
+
import_react4.default.useEffect(() => {
|
|
1908
|
+
if (!columnPersistence || !persistenceAppliedRef.current) return;
|
|
1909
|
+
persistColumnsToStorage();
|
|
1910
|
+
}, [columnPersistence, persistColumnsToStorage]);
|
|
1911
|
+
const [showColumnPicker, setShowColumnPicker] = (0, import_react4.useState)(false);
|
|
1912
|
+
const columnPickerRef = (0, import_react4.useRef)(null);
|
|
1913
|
+
import_react4.default.useEffect(() => {
|
|
1914
|
+
if (!showColumnPicker) return;
|
|
1915
|
+
const close = (e) => {
|
|
1916
|
+
if (columnPickerRef.current && !columnPickerRef.current.contains(e.target)) {
|
|
1917
|
+
setShowColumnPicker(false);
|
|
1918
|
+
}
|
|
1919
|
+
};
|
|
1920
|
+
const onKey = (e) => {
|
|
1921
|
+
if (e.key === "Escape") setShowColumnPicker(false);
|
|
1922
|
+
};
|
|
1923
|
+
document.addEventListener("mousedown", close);
|
|
1924
|
+
document.addEventListener("keydown", onKey);
|
|
1925
|
+
return () => {
|
|
1926
|
+
document.removeEventListener("mousedown", close);
|
|
1927
|
+
document.removeEventListener("keydown", onKey);
|
|
1928
|
+
};
|
|
1929
|
+
}, [showColumnPicker]);
|
|
1710
1930
|
const columnsWithPersistedWidths = (0, import_react4.useMemo)(
|
|
1711
1931
|
() => columns.map((col) => ({
|
|
1712
1932
|
...col,
|
|
@@ -1771,6 +1991,32 @@ function BoltTable({
|
|
|
1771
1991
|
},
|
|
1772
1992
|
[rowKey]
|
|
1773
1993
|
);
|
|
1994
|
+
const deduplicatedRowKeys = (0, import_react4.useMemo)(() => {
|
|
1995
|
+
const seen = /* @__PURE__ */ new Map();
|
|
1996
|
+
return data.map((row, idx) => {
|
|
1997
|
+
const raw = getRowKey(row, idx);
|
|
1998
|
+
const count = seen.get(raw) ?? 0;
|
|
1999
|
+
seen.set(raw, count + 1);
|
|
2000
|
+
return count > 0 ? `${raw}__${idx}` : raw;
|
|
2001
|
+
});
|
|
2002
|
+
}, [data, getRowKey]);
|
|
2003
|
+
const hasDuplicateKeys = (0, import_react4.useMemo)(() => {
|
|
2004
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2005
|
+
for (const row of data) {
|
|
2006
|
+
if (row == null) continue;
|
|
2007
|
+
const k = getRowKey(row, 0);
|
|
2008
|
+
if (seen.has(k)) return true;
|
|
2009
|
+
seen.add(k);
|
|
2010
|
+
}
|
|
2011
|
+
return false;
|
|
2012
|
+
}, [data, getRowKey]);
|
|
2013
|
+
const getSafeRowKey = (0, import_react4.useCallback)(
|
|
2014
|
+
(record, index) => {
|
|
2015
|
+
if (!hasDuplicateKeys) return getRowKey(record, index);
|
|
2016
|
+
return deduplicatedRowKeys[index] ?? getRowKey(record, index);
|
|
2017
|
+
},
|
|
2018
|
+
[getRowKey, hasDuplicateKeys, deduplicatedRowKeys]
|
|
2019
|
+
);
|
|
1774
2020
|
const getRawRowKey = (0, import_react4.useCallback)(
|
|
1775
2021
|
(record, index) => {
|
|
1776
2022
|
if (record == null) return index;
|
|
@@ -1788,16 +2034,13 @@ function BoltTable({
|
|
|
1788
2034
|
},
|
|
1789
2035
|
[rowKey]
|
|
1790
2036
|
);
|
|
1791
|
-
const normalizedSelectedKeys = (0, import_react4.useMemo)(
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
);
|
|
1799
|
-
const getRowKeyRef = (0, import_react4.useRef)(getRowKey);
|
|
1800
|
-
getRowKeyRef.current = getRowKey;
|
|
2037
|
+
const normalizedSelectedKeys = (0, import_react4.useMemo)(() => {
|
|
2038
|
+
const keys = rowSelection?.selectedRowKeys;
|
|
2039
|
+
if (!Array.isArray(keys)) return [];
|
|
2040
|
+
return keys.filter((k) => k != null).map((k) => String(k));
|
|
2041
|
+
}, [rowSelection?.selectedRowKeys]);
|
|
2042
|
+
const getRowKeyRef = (0, import_react4.useRef)(getSafeRowKey);
|
|
2043
|
+
getRowKeyRef.current = getSafeRowKey;
|
|
1801
2044
|
const resolvedExpandedKeysRef = (0, import_react4.useRef)(resolvedExpandedKeys);
|
|
1802
2045
|
resolvedExpandedKeysRef.current = resolvedExpandedKeys;
|
|
1803
2046
|
const toggleExpandRef = (0, import_react4.useRef)(toggleExpand);
|
|
@@ -1980,7 +2223,9 @@ function BoltTable({
|
|
|
1980
2223
|
}
|
|
1981
2224
|
const scrollEl = tableAreaRef.current;
|
|
1982
2225
|
if (!scrollEl) return;
|
|
1983
|
-
const headers = scrollEl.querySelectorAll(
|
|
2226
|
+
const headers = scrollEl.querySelectorAll(
|
|
2227
|
+
"[data-bt-header][data-column-key]"
|
|
2228
|
+
);
|
|
1984
2229
|
let newOverId = null;
|
|
1985
2230
|
headers.forEach((h) => {
|
|
1986
2231
|
const key = h.dataset.columnKey;
|
|
@@ -2022,10 +2267,7 @@ function BoltTable({
|
|
|
2022
2267
|
const newIndex = items.indexOf(currentOverId);
|
|
2023
2268
|
if (oldIndex === -1 || newIndex === -1) return items;
|
|
2024
2269
|
const newOrder = arrayMove(items, oldIndex, newIndex);
|
|
2025
|
-
setTimeout(
|
|
2026
|
-
() => onColumnOrderChangeRef.current?.(newOrder),
|
|
2027
|
-
0
|
|
2028
|
-
);
|
|
2270
|
+
setTimeout(() => onColumnOrderChangeRef.current?.(newOrder), 0);
|
|
2029
2271
|
return newOrder;
|
|
2030
2272
|
});
|
|
2031
2273
|
});
|
|
@@ -2125,9 +2367,7 @@ function BoltTable({
|
|
|
2125
2367
|
[leftPinned, unpinned, rightPinned]
|
|
2126
2368
|
);
|
|
2127
2369
|
const freshOrderedColumns = (0, import_react4.useMemo)(() => {
|
|
2128
|
-
const latestMap = new Map(
|
|
2129
|
-
initialColumnsRef.current.map((c) => [c.key, c])
|
|
2130
|
-
);
|
|
2370
|
+
const latestMap = new Map(initialColumnsRef.current.map((c) => [c.key, c]));
|
|
2131
2371
|
return orderedColumns.map((col) => {
|
|
2132
2372
|
if (col.key === "__select__" || col.key === "__expand__") return col;
|
|
2133
2373
|
const latest = latestMap.get(col.key);
|
|
@@ -2166,6 +2406,11 @@ function BoltTable({
|
|
|
2166
2406
|
}
|
|
2167
2407
|
return offsets;
|
|
2168
2408
|
}, [leftPinned, rightPinned]);
|
|
2409
|
+
const columnGridIndexMap = (0, import_react4.useMemo)(() => {
|
|
2410
|
+
const map = /* @__PURE__ */ new Map();
|
|
2411
|
+
orderedColumns.forEach((col, i) => map.set(col.key, i + 1));
|
|
2412
|
+
return map;
|
|
2413
|
+
}, [orderedColumns]);
|
|
2169
2414
|
const handleTogglePin = (columnKey, pinned) => {
|
|
2170
2415
|
setColumns(
|
|
2171
2416
|
(prev) => prev.map((col) => col.key === columnKey ? { ...col, pinned } : col)
|
|
@@ -2184,22 +2429,27 @@ function BoltTable({
|
|
|
2184
2429
|
};
|
|
2185
2430
|
const [internalRowPinning, setInternalRowPinning] = (0, import_react4.useState)({ top: [], bottom: [] });
|
|
2186
2431
|
const resolvedRowPinning = rowPinning === true ? internalRowPinning : rowPinning && typeof rowPinning === "object" ? rowPinning : void 0;
|
|
2187
|
-
const handleRowPin = (0, import_react4.useCallback)(
|
|
2188
|
-
|
|
2189
|
-
onRowPin
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2432
|
+
const handleRowPin = (0, import_react4.useCallback)(
|
|
2433
|
+
(rk, pinned) => {
|
|
2434
|
+
if (onRowPin) {
|
|
2435
|
+
onRowPin(rk, pinned);
|
|
2436
|
+
return;
|
|
2437
|
+
}
|
|
2438
|
+
if (rowPinning === true) {
|
|
2439
|
+
setInternalRowPinning((prev) => {
|
|
2440
|
+
const rkStr = String(rk);
|
|
2441
|
+
const newTop = (prev.top ?? []).filter((k) => String(k) !== rkStr);
|
|
2442
|
+
const newBottom = (prev.bottom ?? []).filter(
|
|
2443
|
+
(k) => String(k) !== rkStr
|
|
2444
|
+
);
|
|
2445
|
+
if (pinned === "top") newTop.push(rk);
|
|
2446
|
+
else if (pinned === "bottom") newBottom.push(rk);
|
|
2447
|
+
return { top: newTop, bottom: newBottom };
|
|
2448
|
+
});
|
|
2449
|
+
}
|
|
2450
|
+
},
|
|
2451
|
+
[onRowPin, rowPinning]
|
|
2452
|
+
);
|
|
2203
2453
|
const onSortChangeRef = (0, import_react4.useRef)(onSortChange);
|
|
2204
2454
|
onSortChangeRef.current = onSortChange;
|
|
2205
2455
|
const [sortState, setSortState] = (0, import_react4.useState)({ key: "", direction: null });
|
|
@@ -2222,6 +2472,7 @@ function BoltTable({
|
|
|
2222
2472
|
const [columnFilters, setColumnFilters] = (0, import_react4.useState)(
|
|
2223
2473
|
{}
|
|
2224
2474
|
);
|
|
2475
|
+
const [internalGlobalSearch, setInternalGlobalSearch] = (0, import_react4.useState)("");
|
|
2225
2476
|
const handleColumnFilter = (0, import_react4.useCallback)(
|
|
2226
2477
|
(columnKey, value) => {
|
|
2227
2478
|
setColumnFilters((prev) => {
|
|
@@ -2246,6 +2497,20 @@ function BoltTable({
|
|
|
2246
2497
|
columnsLookupRef.current = initialColumns;
|
|
2247
2498
|
const processedData = (0, import_react4.useMemo)(() => {
|
|
2248
2499
|
let result = data;
|
|
2500
|
+
const globalSearch = globalSearchValue ?? internalGlobalSearch;
|
|
2501
|
+
if (globalSearch) {
|
|
2502
|
+
const searchLower = globalSearch.toLowerCase();
|
|
2503
|
+
result = result.filter((row) => {
|
|
2504
|
+
if (row == null) return false;
|
|
2505
|
+
for (const key of Object.keys(row)) {
|
|
2506
|
+
const val = row[key];
|
|
2507
|
+
if (val != null && String(val).toLowerCase().includes(searchLower)) {
|
|
2508
|
+
return true;
|
|
2509
|
+
}
|
|
2510
|
+
}
|
|
2511
|
+
return false;
|
|
2512
|
+
});
|
|
2513
|
+
}
|
|
2249
2514
|
if (!onFilterChangeRef.current) {
|
|
2250
2515
|
const filterKeys = Object.keys(columnFilters);
|
|
2251
2516
|
if (filterKeys.length > 0) {
|
|
@@ -2255,7 +2520,11 @@ function BoltTable({
|
|
|
2255
2520
|
try {
|
|
2256
2521
|
const col = columnsLookupRef.current.find((c) => c.key === key);
|
|
2257
2522
|
if (typeof col?.filterFn === "function") {
|
|
2258
|
-
return col.filterFn(
|
|
2523
|
+
return col.filterFn(
|
|
2524
|
+
columnFilters[key],
|
|
2525
|
+
row,
|
|
2526
|
+
col.dataIndex ?? key
|
|
2527
|
+
);
|
|
2259
2528
|
}
|
|
2260
2529
|
const cellVal = String(row[key] ?? "").toLowerCase();
|
|
2261
2530
|
return cellVal.includes(columnFilters[key].toLowerCase());
|
|
@@ -2298,7 +2567,7 @@ function BoltTable({
|
|
|
2298
2567
|
}
|
|
2299
2568
|
}
|
|
2300
2569
|
return result;
|
|
2301
|
-
}, [data, sortState, columnFilters]);
|
|
2570
|
+
}, [data, sortState, columnFilters, globalSearchValue, internalGlobalSearch]);
|
|
2302
2571
|
const pinnedRowCacheRef = (0, import_react4.useRef)(/* @__PURE__ */ new Map());
|
|
2303
2572
|
const { pinnedTopRows, pinnedBottomRows, unpinnedProcessedData } = (0, import_react4.useMemo)(() => {
|
|
2304
2573
|
if (!resolvedRowPinning || !resolvedRowPinning.top?.length && !resolvedRowPinning.bottom?.length) {
|
|
@@ -2310,19 +2579,23 @@ function BoltTable({
|
|
|
2310
2579
|
};
|
|
2311
2580
|
}
|
|
2312
2581
|
const topKeySet = new Set((resolvedRowPinning.top ?? []).map(String));
|
|
2313
|
-
const bottomKeySet = new Set(
|
|
2582
|
+
const bottomKeySet = new Set(
|
|
2583
|
+
(resolvedRowPinning.bottom ?? []).map(String)
|
|
2584
|
+
);
|
|
2314
2585
|
const topMap = /* @__PURE__ */ new Map();
|
|
2315
2586
|
const bottomMap = /* @__PURE__ */ new Map();
|
|
2316
2587
|
const rest = [];
|
|
2317
2588
|
processedData.forEach((row, idx) => {
|
|
2318
2589
|
if (row == null) return;
|
|
2319
|
-
const key =
|
|
2590
|
+
const key = getSafeRowKey(row, idx);
|
|
2320
2591
|
if (topKeySet.has(key)) {
|
|
2321
2592
|
topMap.set(key, row);
|
|
2322
|
-
if (keepPinnedRowsAcrossPages)
|
|
2593
|
+
if (keepPinnedRowsAcrossPages)
|
|
2594
|
+
pinnedRowCacheRef.current.set(key, row);
|
|
2323
2595
|
} else if (bottomKeySet.has(key)) {
|
|
2324
2596
|
bottomMap.set(key, row);
|
|
2325
|
-
if (keepPinnedRowsAcrossPages)
|
|
2597
|
+
if (keepPinnedRowsAcrossPages)
|
|
2598
|
+
pinnedRowCacheRef.current.set(key, row);
|
|
2326
2599
|
} else {
|
|
2327
2600
|
rest.push(row);
|
|
2328
2601
|
}
|
|
@@ -2340,7 +2613,8 @@ function BoltTable({
|
|
|
2340
2613
|
}
|
|
2341
2614
|
const allPinnedKeys = /* @__PURE__ */ new Set([...topKeySet, ...bottomKeySet]);
|
|
2342
2615
|
for (const cachedKey of pinnedRowCacheRef.current.keys()) {
|
|
2343
|
-
if (!allPinnedKeys.has(cachedKey))
|
|
2616
|
+
if (!allPinnedKeys.has(cachedKey))
|
|
2617
|
+
pinnedRowCacheRef.current.delete(cachedKey);
|
|
2344
2618
|
}
|
|
2345
2619
|
}
|
|
2346
2620
|
const orderedTop = (resolvedRowPinning.top ?? []).map((k) => topMap.get(String(k))).filter((r) => r !== void 0);
|
|
@@ -2350,7 +2624,12 @@ function BoltTable({
|
|
|
2350
2624
|
pinnedBottomRows: orderedBottom,
|
|
2351
2625
|
unpinnedProcessedData: rest
|
|
2352
2626
|
};
|
|
2353
|
-
}, [
|
|
2627
|
+
}, [
|
|
2628
|
+
processedData,
|
|
2629
|
+
resolvedRowPinning,
|
|
2630
|
+
getSafeRowKey,
|
|
2631
|
+
keepPinnedRowsAcrossPages
|
|
2632
|
+
]);
|
|
2354
2633
|
const pinnedTopHeight = pinnedTopRows.length * rowHeight;
|
|
2355
2634
|
const pinnedBottomHeight = pinnedBottomRows.length * rowHeight;
|
|
2356
2635
|
const pinnedTopKeySet = (0, import_react4.useMemo)(
|
|
@@ -2367,9 +2646,7 @@ function BoltTable({
|
|
|
2367
2646
|
}, []);
|
|
2368
2647
|
const [cellContextMenu, setCellContextMenu] = (0, import_react4.useState)(null);
|
|
2369
2648
|
const cellMenuRef = (0, import_react4.useRef)(null);
|
|
2370
|
-
const cellLongPressTimer = (0, import_react4.useRef)(
|
|
2371
|
-
null
|
|
2372
|
-
);
|
|
2649
|
+
const cellLongPressTimer = (0, import_react4.useRef)(null);
|
|
2373
2650
|
const cellTouchStart = (0, import_react4.useRef)(null);
|
|
2374
2651
|
const cancelCellLongPress = (0, import_react4.useCallback)(() => {
|
|
2375
2652
|
if (cellLongPressTimer.current) {
|
|
@@ -2396,10 +2673,11 @@ function BoltTable({
|
|
|
2396
2673
|
};
|
|
2397
2674
|
}, [cellContextMenu]);
|
|
2398
2675
|
const columnFiltersKey = Object.keys(columnFilters).sort().map((k) => `${k}:${columnFilters[k]}`).join("|");
|
|
2676
|
+
const activeGlobalSearch = globalSearchValue ?? internalGlobalSearch;
|
|
2399
2677
|
import_react4.default.useEffect(() => {
|
|
2400
2678
|
setInternalPage(1);
|
|
2401
2679
|
tableAreaRef.current?.scrollTo({ top: 0 });
|
|
2402
|
-
}, [columnFiltersKey]);
|
|
2680
|
+
}, [columnFiltersKey, activeGlobalSearch]);
|
|
2403
2681
|
const DEFAULT_PAGE_SIZE = 15;
|
|
2404
2682
|
const [internalPage, setInternalPage] = (0, import_react4.useState)(1);
|
|
2405
2683
|
const [internalPageSize, setInternalPageSize] = (0, import_react4.useState)(DEFAULT_PAGE_SIZE);
|
|
@@ -2445,6 +2723,17 @@ function BoltTable({
|
|
|
2445
2723
|
return paginatedData;
|
|
2446
2724
|
}, [shimmerData, infiniteLoadingShimmer, paginatedData]);
|
|
2447
2725
|
const measuredExpandedHeights = (0, import_react4.useRef)(/* @__PURE__ */ new Map());
|
|
2726
|
+
const measuredRowHeights = (0, import_react4.useRef)(/* @__PURE__ */ new Map());
|
|
2727
|
+
const handleRowHeightChange = (0, import_react4.useCallback)(
|
|
2728
|
+
(index, height) => {
|
|
2729
|
+
if (!enableDynamicRowHeight) return;
|
|
2730
|
+
const prev = measuredRowHeights.current.get(index);
|
|
2731
|
+
if (prev === height) return;
|
|
2732
|
+
measuredRowHeights.current.set(index, height);
|
|
2733
|
+
rowVirtualizerRef.current?.measure();
|
|
2734
|
+
},
|
|
2735
|
+
[enableDynamicRowHeight]
|
|
2736
|
+
);
|
|
2448
2737
|
const expandedRowMeasureRafRef = (0, import_react4.useRef)(null);
|
|
2449
2738
|
const handleExpandedRowResize = (0, import_react4.useCallback)(
|
|
2450
2739
|
(rk, contentHeight) => {
|
|
@@ -2469,23 +2758,73 @@ function BoltTable({
|
|
|
2469
2758
|
if (shimmerData) return rowHeight;
|
|
2470
2759
|
const item = displayData[index];
|
|
2471
2760
|
if (!item) return rowHeight;
|
|
2472
|
-
const
|
|
2473
|
-
|
|
2761
|
+
const baseHeight = enableDynamicRowHeight ? measuredRowHeights.current.get(index) ?? rowHeight : rowHeight;
|
|
2762
|
+
const key = getSafeRowKey(item, index);
|
|
2763
|
+
if (!resolvedExpandedKeys.has(key)) return baseHeight;
|
|
2474
2764
|
const cached = measuredExpandedHeights.current.get(key);
|
|
2475
|
-
return cached ?
|
|
2765
|
+
return cached ? baseHeight + cached : baseHeight + expandedRowHeight;
|
|
2476
2766
|
},
|
|
2477
2767
|
overscan: 5,
|
|
2478
2768
|
getItemKey: (index) => {
|
|
2479
2769
|
if (shimmerData) return `__shimmer_${index}__`;
|
|
2480
2770
|
const item = displayData[index];
|
|
2481
2771
|
if (!item) return `__fallback_${index}__`;
|
|
2482
|
-
return
|
|
2772
|
+
return getSafeRowKey(item, index);
|
|
2483
2773
|
},
|
|
2484
2774
|
paddingStart: pinnedTopHeight,
|
|
2485
2775
|
paddingEnd: pinnedBottomHeight
|
|
2486
2776
|
});
|
|
2487
2777
|
const rowVirtualizerRef = (0, import_react4.useRef)(rowVirtualizer);
|
|
2488
2778
|
rowVirtualizerRef.current = rowVirtualizer;
|
|
2779
|
+
const scrollLeftRef = (0, import_react4.useRef)(0);
|
|
2780
|
+
const [visibleColumnRange, setVisibleColumnRange] = (0, import_react4.useState)(null);
|
|
2781
|
+
import_react4.default.useEffect(() => {
|
|
2782
|
+
if (!enableColumnVirtualization) return;
|
|
2783
|
+
const el = tableAreaRef.current;
|
|
2784
|
+
if (!el) return;
|
|
2785
|
+
const updateVisibleColumns = () => {
|
|
2786
|
+
const scrollLeft = el.scrollLeft;
|
|
2787
|
+
scrollLeftRef.current = scrollLeft;
|
|
2788
|
+
const viewportWidth = el.clientWidth;
|
|
2789
|
+
const viewStart = scrollLeft;
|
|
2790
|
+
const viewEnd = scrollLeft + viewportWidth;
|
|
2791
|
+
let cumWidth = 0;
|
|
2792
|
+
let startIdx = -1;
|
|
2793
|
+
let endIdx = orderedColumns.length - 1;
|
|
2794
|
+
for (let i = 0; i < orderedColumns.length; i++) {
|
|
2795
|
+
const col = orderedColumns[i];
|
|
2796
|
+
const colWidth = col.width ?? 150;
|
|
2797
|
+
const colStart = cumWidth;
|
|
2798
|
+
const colEnd = cumWidth + colWidth;
|
|
2799
|
+
cumWidth = colEnd;
|
|
2800
|
+
if (col.pinned) continue;
|
|
2801
|
+
if (startIdx === -1 && colEnd > viewStart) {
|
|
2802
|
+
startIdx = Math.max(0, i - 1);
|
|
2803
|
+
}
|
|
2804
|
+
if (colStart > viewEnd) {
|
|
2805
|
+
endIdx = Math.min(orderedColumns.length - 1, i + 1);
|
|
2806
|
+
break;
|
|
2807
|
+
}
|
|
2808
|
+
}
|
|
2809
|
+
if (startIdx === -1) startIdx = 0;
|
|
2810
|
+
setVisibleColumnRange((prev) => {
|
|
2811
|
+
if (prev && prev.start === startIdx && prev.end === endIdx) return prev;
|
|
2812
|
+
return { start: startIdx, end: endIdx };
|
|
2813
|
+
});
|
|
2814
|
+
};
|
|
2815
|
+
updateVisibleColumns();
|
|
2816
|
+
el.addEventListener("scroll", updateVisibleColumns, { passive: true });
|
|
2817
|
+
return () => el.removeEventListener("scroll", updateVisibleColumns);
|
|
2818
|
+
}, [enableColumnVirtualization, orderedColumns]);
|
|
2819
|
+
const virtualizedColumns = (0, import_react4.useMemo)(() => {
|
|
2820
|
+
if (!enableColumnVirtualization || !visibleColumnRange)
|
|
2821
|
+
return freshOrderedColumns;
|
|
2822
|
+
return freshOrderedColumns.filter((col, idx) => {
|
|
2823
|
+
if (col.pinned) return true;
|
|
2824
|
+
if (col.key === "__select__" || col.key === "__expand__") return true;
|
|
2825
|
+
return idx >= visibleColumnRange.start && idx <= visibleColumnRange.end;
|
|
2826
|
+
});
|
|
2827
|
+
}, [enableColumnVirtualization, visibleColumnRange, freshOrderedColumns]);
|
|
2489
2828
|
const resolvedExpandedKeysFingerprint = Array.from(resolvedExpandedKeys).sort().join(",");
|
|
2490
2829
|
import_react4.default.useLayoutEffect(() => {
|
|
2491
2830
|
rowVirtualizer.measure();
|
|
@@ -2552,7 +2891,10 @@ function BoltTable({
|
|
|
2552
2891
|
}, [pgCurrent, needsClientPagination]);
|
|
2553
2892
|
const getPageNumbers = () => {
|
|
2554
2893
|
if (totalPages <= 7)
|
|
2555
|
-
return Array.from(
|
|
2894
|
+
return Array.from(
|
|
2895
|
+
{ length: totalPages },
|
|
2896
|
+
(_, i) => i + 1
|
|
2897
|
+
);
|
|
2556
2898
|
const leftSibling = Math.max(currentPage - 1, 2);
|
|
2557
2899
|
const showLeftEllipsis = leftSibling > 2;
|
|
2558
2900
|
const rightSibling = Math.min(currentPage + 1, totalPages - 1);
|
|
@@ -2563,7 +2905,10 @@ function BoltTable({
|
|
|
2563
2905
|
return [
|
|
2564
2906
|
1,
|
|
2565
2907
|
"ellipsis-left",
|
|
2566
|
-
...Array.from(
|
|
2908
|
+
...Array.from(
|
|
2909
|
+
{ length: 5 },
|
|
2910
|
+
(_, i) => totalPages - 4 + i
|
|
2911
|
+
)
|
|
2567
2912
|
];
|
|
2568
2913
|
return [
|
|
2569
2914
|
1,
|
|
@@ -2634,6 +2979,190 @@ function BoltTable({
|
|
|
2634
2979
|
}
|
|
2635
2980
|
${onRowClick ? "[data-bt-cell] { cursor: pointer; }" : ""}
|
|
2636
2981
|
` }),
|
|
2982
|
+
(!hideGlobalSearch || showColumnSettings) && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
2983
|
+
"div",
|
|
2984
|
+
{
|
|
2985
|
+
style: {
|
|
2986
|
+
display: "flex",
|
|
2987
|
+
alignItems: "center",
|
|
2988
|
+
gap: 8,
|
|
2989
|
+
padding: "6px 8px",
|
|
2990
|
+
borderBottom: "1px solid rgba(128,128,128,0.2)",
|
|
2991
|
+
fontSize: 12,
|
|
2992
|
+
flexShrink: 0
|
|
2993
|
+
},
|
|
2994
|
+
children: [
|
|
2995
|
+
!hideGlobalSearch && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
2996
|
+
"div",
|
|
2997
|
+
{
|
|
2998
|
+
style: {
|
|
2999
|
+
display: "flex",
|
|
3000
|
+
alignItems: "center",
|
|
3001
|
+
gap: 4,
|
|
3002
|
+
flex: "1 1 0%",
|
|
3003
|
+
position: "relative"
|
|
3004
|
+
},
|
|
3005
|
+
children: [
|
|
3006
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
3007
|
+
"span",
|
|
3008
|
+
{
|
|
3009
|
+
style: { display: "flex", color: "GrayText", flexShrink: 0 },
|
|
3010
|
+
children: icons?.search ?? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SearchIcon, { style: { width: 14, height: 14 } })
|
|
3011
|
+
}
|
|
3012
|
+
),
|
|
3013
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
3014
|
+
"input",
|
|
3015
|
+
{
|
|
3016
|
+
type: "text",
|
|
3017
|
+
placeholder: "Search all columns...",
|
|
3018
|
+
value: globalSearchValue ?? internalGlobalSearch,
|
|
3019
|
+
onChange: (e) => {
|
|
3020
|
+
const v = e.target.value;
|
|
3021
|
+
if (onGlobalSearchChange) onGlobalSearchChange(v);
|
|
3022
|
+
else setInternalGlobalSearch(v);
|
|
3023
|
+
},
|
|
3024
|
+
style: {
|
|
3025
|
+
flex: "1 1 0%",
|
|
3026
|
+
border: "none",
|
|
3027
|
+
outline: "none",
|
|
3028
|
+
background: "transparent",
|
|
3029
|
+
font: "inherit",
|
|
3030
|
+
color: "inherit",
|
|
3031
|
+
padding: "4px 6px",
|
|
3032
|
+
minWidth: 0
|
|
3033
|
+
}
|
|
3034
|
+
}
|
|
3035
|
+
),
|
|
3036
|
+
(globalSearchValue ?? internalGlobalSearch) && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
3037
|
+
"button",
|
|
3038
|
+
{
|
|
3039
|
+
type: "button",
|
|
3040
|
+
onClick: () => {
|
|
3041
|
+
if (onGlobalSearchChange) onGlobalSearchChange("");
|
|
3042
|
+
else setInternalGlobalSearch("");
|
|
3043
|
+
},
|
|
3044
|
+
style: {
|
|
3045
|
+
display: "flex",
|
|
3046
|
+
alignItems: "center",
|
|
3047
|
+
justifyContent: "center",
|
|
3048
|
+
background: "none",
|
|
3049
|
+
border: "none",
|
|
3050
|
+
cursor: "pointer",
|
|
3051
|
+
padding: 2,
|
|
3052
|
+
color: "GrayText",
|
|
3053
|
+
flexShrink: 0
|
|
3054
|
+
},
|
|
3055
|
+
children: icons?.close ?? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(XIcon, { style: { width: 12, height: 12 } })
|
|
3056
|
+
}
|
|
3057
|
+
)
|
|
3058
|
+
]
|
|
3059
|
+
}
|
|
3060
|
+
),
|
|
3061
|
+
toolbarContent,
|
|
3062
|
+
showColumnSettings && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { position: "relative", flexShrink: 0 }, children: [
|
|
3063
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
3064
|
+
"button",
|
|
3065
|
+
{
|
|
3066
|
+
type: "button",
|
|
3067
|
+
onClick: () => setShowColumnPicker((p) => !p),
|
|
3068
|
+
style: {
|
|
3069
|
+
display: "flex",
|
|
3070
|
+
alignItems: "center",
|
|
3071
|
+
justifyContent: "center",
|
|
3072
|
+
background: "none",
|
|
3073
|
+
border: "1px solid rgba(128,128,128,0.2)",
|
|
3074
|
+
borderRadius: 4,
|
|
3075
|
+
cursor: "pointer",
|
|
3076
|
+
padding: "4px 6px",
|
|
3077
|
+
color: "inherit",
|
|
3078
|
+
gap: 4,
|
|
3079
|
+
fontSize: 12
|
|
3080
|
+
},
|
|
3081
|
+
title: "Column settings",
|
|
3082
|
+
children: [
|
|
3083
|
+
icons?.columns ?? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ColumnsIcon, { style: { width: 14, height: 14 } }),
|
|
3084
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: columnSettingsLabel ?? "Columns" })
|
|
3085
|
+
]
|
|
3086
|
+
}
|
|
3087
|
+
),
|
|
3088
|
+
showColumnPicker && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
3089
|
+
"div",
|
|
3090
|
+
{
|
|
3091
|
+
ref: columnPickerRef,
|
|
3092
|
+
style: {
|
|
3093
|
+
position: "absolute",
|
|
3094
|
+
top: "100%",
|
|
3095
|
+
right: 0,
|
|
3096
|
+
zIndex: 99999,
|
|
3097
|
+
minWidth: 200,
|
|
3098
|
+
maxHeight: 320,
|
|
3099
|
+
overflowY: "auto",
|
|
3100
|
+
borderRadius: 8,
|
|
3101
|
+
border: "1px solid rgba(128,128,128,0.2)",
|
|
3102
|
+
boxShadow: "0 4px 24px rgba(0,0,0,0.12)",
|
|
3103
|
+
backdropFilter: "blur(16px)",
|
|
3104
|
+
WebkitBackdropFilter: "blur(16px)",
|
|
3105
|
+
backgroundColor: "rgba(128,128,128,0.08)",
|
|
3106
|
+
padding: "4px 0",
|
|
3107
|
+
marginTop: 4
|
|
3108
|
+
},
|
|
3109
|
+
children: initialColumns.filter(
|
|
3110
|
+
(c) => c.key !== "__select__" && c.key !== "__expand__"
|
|
3111
|
+
).map((col) => {
|
|
3112
|
+
const current = columns.find((c) => c.key === col.key);
|
|
3113
|
+
const isHidden = current?.hidden ?? false;
|
|
3114
|
+
const isPinned = !!current?.pinned;
|
|
3115
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
3116
|
+
"label",
|
|
3117
|
+
{
|
|
3118
|
+
style: {
|
|
3119
|
+
display: "flex",
|
|
3120
|
+
alignItems: "center",
|
|
3121
|
+
gap: 8,
|
|
3122
|
+
padding: "6px 12px",
|
|
3123
|
+
cursor: isPinned ? "not-allowed" : "pointer",
|
|
3124
|
+
opacity: isPinned ? 0.5 : 1,
|
|
3125
|
+
fontSize: 12
|
|
3126
|
+
},
|
|
3127
|
+
children: [
|
|
3128
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
3129
|
+
"input",
|
|
3130
|
+
{
|
|
3131
|
+
type: "checkbox",
|
|
3132
|
+
checked: !isHidden,
|
|
3133
|
+
disabled: isPinned,
|
|
3134
|
+
onChange: () => {
|
|
3135
|
+
if (isPinned) return;
|
|
3136
|
+
handleToggleHide(col.key);
|
|
3137
|
+
},
|
|
3138
|
+
style: {
|
|
3139
|
+
cursor: isPinned ? "not-allowed" : "pointer",
|
|
3140
|
+
accentColor
|
|
3141
|
+
}
|
|
3142
|
+
}
|
|
3143
|
+
),
|
|
3144
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
3145
|
+
"span",
|
|
3146
|
+
{
|
|
3147
|
+
style: {
|
|
3148
|
+
overflow: "hidden",
|
|
3149
|
+
textOverflow: "ellipsis",
|
|
3150
|
+
whiteSpace: "nowrap"
|
|
3151
|
+
},
|
|
3152
|
+
children: typeof col.title === "string" ? col.title : col.key
|
|
3153
|
+
}
|
|
3154
|
+
)
|
|
3155
|
+
]
|
|
3156
|
+
},
|
|
3157
|
+
col.key
|
|
3158
|
+
);
|
|
3159
|
+
})
|
|
3160
|
+
}
|
|
3161
|
+
)
|
|
3162
|
+
] })
|
|
3163
|
+
]
|
|
3164
|
+
}
|
|
3165
|
+
),
|
|
2637
3166
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2638
3167
|
"div",
|
|
2639
3168
|
{
|
|
@@ -2778,19 +3307,20 @@ function BoltTable({
|
|
|
2778
3307
|
...isEmpty ? { height: "100%" } : {}
|
|
2779
3308
|
},
|
|
2780
3309
|
onContextMenu: (e) => {
|
|
2781
|
-
const cell = e.target.closest(
|
|
3310
|
+
const cell = e.target.closest(
|
|
3311
|
+
"[data-bt-cell]"
|
|
3312
|
+
);
|
|
2782
3313
|
if (!cell) return;
|
|
2783
3314
|
const rk = cell.dataset.rowKey;
|
|
2784
3315
|
const ck = cell.dataset.columnKey;
|
|
2785
3316
|
if (!rk || !ck) return;
|
|
2786
|
-
const col = freshOrderedColumns.find(
|
|
2787
|
-
(c) => c.key === ck
|
|
2788
|
-
);
|
|
3317
|
+
const col = freshOrderedColumns.find((c) => c.key === ck);
|
|
2789
3318
|
const hasCopy = !!col?.copy;
|
|
2790
3319
|
const hasRowPin = !!rowPinning;
|
|
2791
3320
|
const hasCellItems = col?.columnCellContextMenuItems && col.columnCellContextMenuItems.length > 0;
|
|
2792
3321
|
const hasEdit = !!col?.editable && !col?.render && !!onEdit;
|
|
2793
|
-
if (!hasCopy && !hasRowPin && !hasCellItems && !hasEdit)
|
|
3322
|
+
if (!hasCopy && !hasRowPin && !hasCellItems && !hasEdit)
|
|
3323
|
+
return;
|
|
2794
3324
|
e.preventDefault();
|
|
2795
3325
|
setCellContextMenu({
|
|
2796
3326
|
x: Math.min(e.clientX, window.innerWidth - 200),
|
|
@@ -2801,7 +3331,9 @@ function BoltTable({
|
|
|
2801
3331
|
},
|
|
2802
3332
|
onTouchStart: (e) => {
|
|
2803
3333
|
cancelCellLongPress();
|
|
2804
|
-
const cell = e.target.closest(
|
|
3334
|
+
const cell = e.target.closest(
|
|
3335
|
+
"[data-bt-cell]"
|
|
3336
|
+
);
|
|
2805
3337
|
if (!cell) return;
|
|
2806
3338
|
const touch = e.touches[0];
|
|
2807
3339
|
cellTouchStart.current = {
|
|
@@ -2813,14 +3345,13 @@ function BoltTable({
|
|
|
2813
3345
|
cellLongPressTimer.current = setTimeout(() => {
|
|
2814
3346
|
cellLongPressTimer.current = null;
|
|
2815
3347
|
if (!rk || !ck) return;
|
|
2816
|
-
const col = freshOrderedColumns.find(
|
|
2817
|
-
(c) => c.key === ck
|
|
2818
|
-
);
|
|
3348
|
+
const col = freshOrderedColumns.find((c) => c.key === ck);
|
|
2819
3349
|
const hasCopy = !!col?.copy;
|
|
2820
3350
|
const hasRowPin = !!rowPinning;
|
|
2821
3351
|
const hasCellItems = col?.columnCellContextMenuItems && col.columnCellContextMenuItems.length > 0;
|
|
2822
3352
|
const hasEdit = !!col?.editable && !col?.render && !!onEdit;
|
|
2823
|
-
if (!hasCopy && !hasRowPin && !hasCellItems && !hasEdit)
|
|
3353
|
+
if (!hasCopy && !hasRowPin && !hasCellItems && !hasEdit)
|
|
3354
|
+
return;
|
|
2824
3355
|
setCellContextMenu({
|
|
2825
3356
|
x: Math.min(touch.clientX, window.innerWidth - 200),
|
|
2826
3357
|
y: Math.min(touch.clientY, window.innerHeight - 200),
|
|
@@ -2841,7 +3372,8 @@ function BoltTable({
|
|
|
2841
3372
|
onTouchCancel: cancelCellLongPress,
|
|
2842
3373
|
onClick: onRowClick ? (e) => {
|
|
2843
3374
|
const target = e.target;
|
|
2844
|
-
if (target.closest("input, button, a, select, textarea"))
|
|
3375
|
+
if (target.closest("input, button, a, select, textarea"))
|
|
3376
|
+
return;
|
|
2845
3377
|
const cell = target.closest("[data-bt-cell]");
|
|
2846
3378
|
if (!cell) return;
|
|
2847
3379
|
const rk = cell.dataset.rowKey;
|
|
@@ -2849,21 +3381,21 @@ function BoltTable({
|
|
|
2849
3381
|
for (let i = 0; i < displayData.length; i++) {
|
|
2850
3382
|
const row = displayData[i];
|
|
2851
3383
|
if (row == null) continue;
|
|
2852
|
-
if (
|
|
3384
|
+
if (getSafeRowKey(row, i) === rk) {
|
|
2853
3385
|
onRowClick(row, i, e);
|
|
2854
3386
|
return;
|
|
2855
3387
|
}
|
|
2856
3388
|
}
|
|
2857
3389
|
for (let i = 0; i < pinnedTopRows.length; i++) {
|
|
2858
3390
|
if (pinnedTopRows[i] == null) continue;
|
|
2859
|
-
if (
|
|
3391
|
+
if (getSafeRowKey(pinnedTopRows[i], i) === rk) {
|
|
2860
3392
|
onRowClick(pinnedTopRows[i], i, e);
|
|
2861
3393
|
return;
|
|
2862
3394
|
}
|
|
2863
3395
|
}
|
|
2864
3396
|
for (let i = 0; i < pinnedBottomRows.length; i++) {
|
|
2865
3397
|
if (pinnedBottomRows[i] == null) continue;
|
|
2866
|
-
if (
|
|
3398
|
+
if (getSafeRowKey(pinnedBottomRows[i], i) === rk) {
|
|
2867
3399
|
onRowClick(pinnedBottomRows[i], i, e);
|
|
2868
3400
|
return;
|
|
2869
3401
|
}
|
|
@@ -2973,7 +3505,11 @@ function BoltTable({
|
|
|
2973
3505
|
});
|
|
2974
3506
|
}
|
|
2975
3507
|
},
|
|
2976
|
-
style: {
|
|
3508
|
+
style: {
|
|
3509
|
+
cursor: "pointer",
|
|
3510
|
+
accentColor,
|
|
3511
|
+
backgroundColor: "#94A3B8"
|
|
3512
|
+
}
|
|
2977
3513
|
}
|
|
2978
3514
|
)
|
|
2979
3515
|
},
|
|
@@ -3033,7 +3569,10 @@ function BoltTable({
|
|
|
3033
3569
|
filterValue: columnFilters[column.key] ?? "",
|
|
3034
3570
|
onFilter: handleColumnFilter,
|
|
3035
3571
|
onClearFilter: handleClearFilter,
|
|
3036
|
-
customContextMenuItems: column.columnHeaderContextMenuItems ? [
|
|
3572
|
+
customContextMenuItems: column.columnHeaderContextMenuItems ? [
|
|
3573
|
+
...columnContextMenuItems ?? [],
|
|
3574
|
+
...column.columnHeaderContextMenuItems
|
|
3575
|
+
] : columnContextMenuItems,
|
|
3037
3576
|
disabledFilters,
|
|
3038
3577
|
headerGridRow: leafGridRow,
|
|
3039
3578
|
headerHeight: leafHeight,
|
|
@@ -3085,14 +3624,14 @@ function BoltTable({
|
|
|
3085
3624
|
TableBody_default,
|
|
3086
3625
|
{
|
|
3087
3626
|
data: displayData,
|
|
3088
|
-
orderedColumns:
|
|
3627
|
+
orderedColumns: virtualizedColumns,
|
|
3089
3628
|
rowVirtualizer,
|
|
3090
3629
|
columnOffsets,
|
|
3091
3630
|
styles,
|
|
3092
3631
|
classNames,
|
|
3093
3632
|
rowSelection: !showShimmer ? rowSelection : void 0,
|
|
3094
3633
|
normalizedSelectedKeys,
|
|
3095
|
-
getRowKey,
|
|
3634
|
+
getRowKey: getSafeRowKey,
|
|
3096
3635
|
getRawRowKey,
|
|
3097
3636
|
expandable: !showShimmer ? expandable : void 0,
|
|
3098
3637
|
resolvedExpandedKeys,
|
|
@@ -3113,7 +3652,10 @@ function BoltTable({
|
|
|
3113
3652
|
bodyGridRow: hasColumnGroups ? 3 : 2,
|
|
3114
3653
|
onEdit,
|
|
3115
3654
|
editingCell,
|
|
3116
|
-
onEditComplete: handleEditComplete
|
|
3655
|
+
onEditComplete: handleEditComplete,
|
|
3656
|
+
enableDynamicRowHeight,
|
|
3657
|
+
onRowHeightChange: handleRowHeightChange,
|
|
3658
|
+
columnGridIndexMap
|
|
3117
3659
|
}
|
|
3118
3660
|
)
|
|
3119
3661
|
]
|
|
@@ -3143,39 +3685,53 @@ function BoltTable({
|
|
|
3143
3685
|
...styles.pagination
|
|
3144
3686
|
},
|
|
3145
3687
|
children: [
|
|
3146
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
"
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3688
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
3689
|
+
"div",
|
|
3690
|
+
{
|
|
3691
|
+
style: { display: "flex", flex: "1 1 0%", alignItems: "center" },
|
|
3692
|
+
children: (() => {
|
|
3693
|
+
const rangeStart = total > 0 ? (currentPage - 1) * pageSize + 1 : 0;
|
|
3694
|
+
const rangeEnd = Math.min(currentPage * pageSize, total);
|
|
3695
|
+
return typeof pagination === "object" && pagination?.showTotal ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
3696
|
+
"span",
|
|
3697
|
+
{
|
|
3698
|
+
className: classNames.paginationInfo ?? "",
|
|
3699
|
+
style: {
|
|
3700
|
+
color: "GrayText",
|
|
3701
|
+
fontSize: 12,
|
|
3702
|
+
...styles.paginationInfo
|
|
3703
|
+
},
|
|
3704
|
+
children: [
|
|
3705
|
+
"Showing",
|
|
3706
|
+
" ",
|
|
3707
|
+
pagination.showTotal(total, [rangeStart, rangeEnd]),
|
|
3708
|
+
" of",
|
|
3709
|
+
" ",
|
|
3710
|
+
total,
|
|
3711
|
+
" items"
|
|
3712
|
+
]
|
|
3713
|
+
}
|
|
3714
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
3715
|
+
"span",
|
|
3716
|
+
{
|
|
3717
|
+
className: classNames.paginationInfo ?? "",
|
|
3718
|
+
style: {
|
|
3719
|
+
color: "GrayText",
|
|
3720
|
+
fontSize: 12,
|
|
3721
|
+
...styles.paginationInfo
|
|
3722
|
+
},
|
|
3723
|
+
children: [
|
|
3724
|
+
rangeStart,
|
|
3725
|
+
"\u2013",
|
|
3726
|
+
rangeEnd,
|
|
3727
|
+
" of ",
|
|
3728
|
+
total
|
|
3729
|
+
]
|
|
3730
|
+
}
|
|
3731
|
+
);
|
|
3732
|
+
})()
|
|
3733
|
+
}
|
|
3734
|
+
),
|
|
3179
3735
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
3180
3736
|
"div",
|
|
3181
3737
|
{
|
|
@@ -3458,9 +4014,7 @@ function BoltTable({
|
|
|
3458
4014
|
(c) => c.key === cellContextMenu.columnKey
|
|
3459
4015
|
);
|
|
3460
4016
|
const isPinnedTop = pinnedTopKeySet.has(cellContextMenu.rowKey);
|
|
3461
|
-
const isPinnedBottom = pinnedBottomKeySet.has(
|
|
3462
|
-
cellContextMenu.rowKey
|
|
3463
|
-
);
|
|
4017
|
+
const isPinnedBottom = pinnedBottomKeySet.has(cellContextMenu.rowKey);
|
|
3464
4018
|
const hasCopy = !!menuCol?.copy;
|
|
3465
4019
|
const hasRowPin = !!rowPinning;
|
|
3466
4020
|
const hasEdit = !!menuCol?.editable && !menuCol?.render && !!onEdit;
|
|
@@ -3473,7 +4027,7 @@ function BoltTable({
|
|
|
3473
4027
|
];
|
|
3474
4028
|
for (let i = 0; i < allRows.length; i++) {
|
|
3475
4029
|
if (allRows[i] == null) continue;
|
|
3476
|
-
const rk =
|
|
4030
|
+
const rk = getSafeRowKey(allRows[i], i);
|
|
3477
4031
|
if (rk === cellContextMenu.rowKey) {
|
|
3478
4032
|
menuRecord = allRows[i];
|
|
3479
4033
|
menuRowIndex = i;
|
|
@@ -3675,7 +4229,20 @@ function BoltTable({
|
|
|
3675
4229
|
setCellContextMenu(null);
|
|
3676
4230
|
},
|
|
3677
4231
|
children: [
|
|
3678
|
-
item.icon && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
4232
|
+
item.icon && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
4233
|
+
"span",
|
|
4234
|
+
{
|
|
4235
|
+
style: {
|
|
4236
|
+
display: "flex",
|
|
4237
|
+
width: 14,
|
|
4238
|
+
height: 14,
|
|
4239
|
+
alignItems: "center",
|
|
4240
|
+
justifyContent: "center",
|
|
4241
|
+
flexShrink: 0
|
|
4242
|
+
},
|
|
4243
|
+
children: item.icon
|
|
4244
|
+
}
|
|
4245
|
+
),
|
|
3679
4246
|
item.label
|
|
3680
4247
|
]
|
|
3681
4248
|
},
|