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.mjs
CHANGED
|
@@ -90,6 +90,18 @@ var EyeOffIcon = ({ style, className }) => /* @__PURE__ */ jsxs("svg", { ...svgB
|
|
|
90
90
|
/* @__PURE__ */ 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" }),
|
|
91
91
|
/* @__PURE__ */ jsx("line", { x1: "2", x2: "22", y1: "2", y2: "22" })
|
|
92
92
|
] });
|
|
93
|
+
var SearchIcon = ({ style, className }) => /* @__PURE__ */ jsxs("svg", { ...svgBase, style, className, children: [
|
|
94
|
+
/* @__PURE__ */ jsx("circle", { cx: "11", cy: "11", r: "8" }),
|
|
95
|
+
/* @__PURE__ */ jsx("path", { d: "m21 21-4.3-4.3" })
|
|
96
|
+
] });
|
|
97
|
+
var ColumnsIcon = ({ style, className }) => /* @__PURE__ */ jsxs("svg", { ...svgBase, style, className, children: [
|
|
98
|
+
/* @__PURE__ */ jsx("rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", ry: "2" }),
|
|
99
|
+
/* @__PURE__ */ jsx("line", { x1: "12", x2: "12", y1: "3", y2: "21" })
|
|
100
|
+
] });
|
|
101
|
+
var XIcon = ({ style, className }) => /* @__PURE__ */ jsxs("svg", { ...svgBase, style, className, children: [
|
|
102
|
+
/* @__PURE__ */ jsx("path", { d: "M18 6 6 18" }),
|
|
103
|
+
/* @__PURE__ */ jsx("path", { d: "m6 6 12 12" })
|
|
104
|
+
] });
|
|
93
105
|
|
|
94
106
|
// src/DraggableHeader.tsx
|
|
95
107
|
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
@@ -762,7 +774,13 @@ ResizeOverlay.displayName = "ResizeOverlay";
|
|
|
762
774
|
var ResizeOverlay_default = ResizeOverlay;
|
|
763
775
|
|
|
764
776
|
// src/TableBody.tsx
|
|
765
|
-
import React3, {
|
|
777
|
+
import React3, {
|
|
778
|
+
useCallback,
|
|
779
|
+
useEffect as useEffect2,
|
|
780
|
+
useMemo,
|
|
781
|
+
useRef as useRef3,
|
|
782
|
+
useState as useState2
|
|
783
|
+
} from "react";
|
|
766
784
|
import { Fragment as Fragment3, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
767
785
|
var SHIMMER_WIDTHS = [55, 70, 45, 80, 60, 50, 75, 65];
|
|
768
786
|
var EditableCell = ({
|
|
@@ -789,7 +807,15 @@ var EditableCell = ({
|
|
|
789
807
|
onEdit(coerced, record, column.dataIndex, rowIndex);
|
|
790
808
|
}
|
|
791
809
|
onEditComplete();
|
|
792
|
-
}, [
|
|
810
|
+
}, [
|
|
811
|
+
draft,
|
|
812
|
+
value,
|
|
813
|
+
column.dataIndex,
|
|
814
|
+
record,
|
|
815
|
+
rowIndex,
|
|
816
|
+
onEdit,
|
|
817
|
+
onEditComplete
|
|
818
|
+
]);
|
|
793
819
|
const cancel = useCallback(() => {
|
|
794
820
|
onEditComplete();
|
|
795
821
|
}, [onEditComplete]);
|
|
@@ -891,7 +917,11 @@ var Cell = React3.memo(
|
|
|
891
917
|
rowSelection.onSelect?.(record, true, [record], e.nativeEvent);
|
|
892
918
|
rowSelection.onChange?.([rawKey], [record], { type: "single" });
|
|
893
919
|
},
|
|
894
|
-
style: {
|
|
920
|
+
style: {
|
|
921
|
+
cursor: "pointer",
|
|
922
|
+
accentColor,
|
|
923
|
+
backgroundColor: "#94A3B8"
|
|
924
|
+
}
|
|
895
925
|
}
|
|
896
926
|
) : /* @__PURE__ */ jsx4(
|
|
897
927
|
"input",
|
|
@@ -917,7 +947,11 @@ var Cell = React3.memo(
|
|
|
917
947
|
type: "multiple"
|
|
918
948
|
});
|
|
919
949
|
},
|
|
920
|
-
style: {
|
|
950
|
+
style: {
|
|
951
|
+
cursor: "pointer",
|
|
952
|
+
accentColor,
|
|
953
|
+
backgroundColor: "#94A3B8"
|
|
954
|
+
}
|
|
921
955
|
}
|
|
922
956
|
);
|
|
923
957
|
return /* @__PURE__ */ jsx4(
|
|
@@ -1053,6 +1087,33 @@ var MeasuredExpandedRow = React3.memo(
|
|
|
1053
1087
|
}
|
|
1054
1088
|
);
|
|
1055
1089
|
MeasuredExpandedRow.displayName = "MeasuredExpandedRow";
|
|
1090
|
+
var DynamicRowMeasurer = React3.memo(
|
|
1091
|
+
({
|
|
1092
|
+
index,
|
|
1093
|
+
onHeightChange,
|
|
1094
|
+
children
|
|
1095
|
+
}) => {
|
|
1096
|
+
const ref = useRef3(null);
|
|
1097
|
+
const onHeightChangeRef = useRef3(onHeightChange);
|
|
1098
|
+
useEffect2(() => {
|
|
1099
|
+
onHeightChangeRef.current = onHeightChange;
|
|
1100
|
+
}, [onHeightChange]);
|
|
1101
|
+
useEffect2(() => {
|
|
1102
|
+
const el = ref.current;
|
|
1103
|
+
if (!el) return;
|
|
1104
|
+
const observer = new ResizeObserver((entries) => {
|
|
1105
|
+
const height = entries[0]?.borderBoxSize?.[0]?.blockSize;
|
|
1106
|
+
if (height != null && height > 0) {
|
|
1107
|
+
onHeightChangeRef.current(index, Math.ceil(height));
|
|
1108
|
+
}
|
|
1109
|
+
});
|
|
1110
|
+
observer.observe(el);
|
|
1111
|
+
return () => observer.disconnect();
|
|
1112
|
+
}, [index]);
|
|
1113
|
+
return /* @__PURE__ */ jsx4("div", { ref, children });
|
|
1114
|
+
}
|
|
1115
|
+
);
|
|
1116
|
+
DynamicRowMeasurer.displayName = "DynamicRowMeasurer";
|
|
1056
1117
|
var TableBody = ({
|
|
1057
1118
|
data,
|
|
1058
1119
|
orderedColumns,
|
|
@@ -1082,11 +1143,17 @@ var TableBody = ({
|
|
|
1082
1143
|
bodyGridRow = 2,
|
|
1083
1144
|
onEdit,
|
|
1084
1145
|
editingCell,
|
|
1085
|
-
onEditComplete
|
|
1146
|
+
onEditComplete,
|
|
1147
|
+
enableDynamicRowHeight = false,
|
|
1148
|
+
onRowHeightChange,
|
|
1149
|
+
columnGridIndexMap
|
|
1086
1150
|
}) => {
|
|
1087
1151
|
const virtualItems = rowVirtualizer.getVirtualItems();
|
|
1088
1152
|
const totalSize = rowVirtualizer.getTotalSize();
|
|
1089
|
-
const selectedKeySet = useMemo(
|
|
1153
|
+
const selectedKeySet = useMemo(
|
|
1154
|
+
() => new Set(normalizedSelectedKeys),
|
|
1155
|
+
[normalizedSelectedKeys]
|
|
1156
|
+
);
|
|
1090
1157
|
const safeData = data ?? [];
|
|
1091
1158
|
const safeColumns = orderedColumns ?? [];
|
|
1092
1159
|
const allDataForSelection = useMemo(() => {
|
|
@@ -1102,8 +1169,9 @@ var TableBody = ({
|
|
|
1102
1169
|
let zIndex = 0;
|
|
1103
1170
|
if (col.key === "__select__" || col.key === "__expand__") zIndex = 11;
|
|
1104
1171
|
else if (isPinned) zIndex = 2;
|
|
1172
|
+
const gridCol = columnGridIndexMap?.get(col.key) ?? colIndex + 1;
|
|
1105
1173
|
const style = {
|
|
1106
|
-
gridColumn:
|
|
1174
|
+
gridColumn: gridCol,
|
|
1107
1175
|
gridRow: bodyGridRow,
|
|
1108
1176
|
height: `${totalSize}px`,
|
|
1109
1177
|
position: isPinned ? "sticky" : "relative",
|
|
@@ -1118,7 +1186,7 @@ var TableBody = ({
|
|
|
1118
1186
|
}
|
|
1119
1187
|
return { key: col.key, style, isPinned };
|
|
1120
1188
|
});
|
|
1121
|
-
}, [safeColumns, columnOffsets, totalSize, styles, bodyGridRow]);
|
|
1189
|
+
}, [safeColumns, columnOffsets, totalSize, styles, bodyGridRow, columnGridIndexMap]);
|
|
1122
1190
|
if (safeData.length === 0 || safeColumns.length === 0) return null;
|
|
1123
1191
|
return /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
1124
1192
|
columnStyles.map((colStyle, colIndex) => {
|
|
@@ -1169,15 +1237,58 @@ var TableBody = ({
|
|
|
1169
1237
|
top: `${virtualRow.start}px`,
|
|
1170
1238
|
left: 0,
|
|
1171
1239
|
right: 0,
|
|
1172
|
-
height: `${virtualRow.size}px`,
|
|
1173
|
-
|
|
1240
|
+
height: enableDynamicRowHeight ? void 0 : `${virtualRow.size}px`,
|
|
1241
|
+
minHeight: enableDynamicRowHeight ? `${rowHeight}px` : void 0
|
|
1174
1242
|
},
|
|
1175
|
-
children: /* @__PURE__ */ jsx4(
|
|
1243
|
+
children: enableDynamicRowHeight && onRowHeightChange && colIndex === 0 ? /* @__PURE__ */ jsx4(
|
|
1244
|
+
DynamicRowMeasurer,
|
|
1245
|
+
{
|
|
1246
|
+
index: virtualRow.index,
|
|
1247
|
+
onHeightChange: onRowHeightChange,
|
|
1248
|
+
children: /* @__PURE__ */ jsx4(
|
|
1249
|
+
"div",
|
|
1250
|
+
{
|
|
1251
|
+
style: {
|
|
1252
|
+
minHeight: `${rowHeight}px`,
|
|
1253
|
+
position: "relative",
|
|
1254
|
+
...rowSty
|
|
1255
|
+
},
|
|
1256
|
+
children: /* @__PURE__ */ jsx4(
|
|
1257
|
+
Cell,
|
|
1258
|
+
{
|
|
1259
|
+
value: cellValue,
|
|
1260
|
+
record: row,
|
|
1261
|
+
column: col,
|
|
1262
|
+
rowIndex: virtualRow.index,
|
|
1263
|
+
classNames,
|
|
1264
|
+
styles,
|
|
1265
|
+
isSelected,
|
|
1266
|
+
isExpanded,
|
|
1267
|
+
rowSelection,
|
|
1268
|
+
normalizedSelectedKeys,
|
|
1269
|
+
rowKey,
|
|
1270
|
+
allData: allDataForSelection,
|
|
1271
|
+
getRowKey,
|
|
1272
|
+
getRawRowKey,
|
|
1273
|
+
accentColor,
|
|
1274
|
+
isLoading: isRowShimmer,
|
|
1275
|
+
recordFingerprint,
|
|
1276
|
+
onEdit,
|
|
1277
|
+
isEditing: editingCell?.rowKey === rowKey && editingCell?.columnKey === col.key,
|
|
1278
|
+
onEditComplete
|
|
1279
|
+
}
|
|
1280
|
+
)
|
|
1281
|
+
}
|
|
1282
|
+
)
|
|
1283
|
+
}
|
|
1284
|
+
) : /* @__PURE__ */ jsx4(
|
|
1176
1285
|
"div",
|
|
1177
1286
|
{
|
|
1178
1287
|
style: {
|
|
1179
|
-
height: `${rowHeight}px`,
|
|
1180
|
-
|
|
1288
|
+
height: enableDynamicRowHeight ? void 0 : `${rowHeight}px`,
|
|
1289
|
+
minHeight: enableDynamicRowHeight ? `${rowHeight}px` : void 0,
|
|
1290
|
+
position: "relative",
|
|
1291
|
+
...rowSty
|
|
1181
1292
|
},
|
|
1182
1293
|
children: /* @__PURE__ */ jsx4(
|
|
1183
1294
|
Cell,
|
|
@@ -1232,7 +1343,12 @@ var TableBody = ({
|
|
|
1232
1343
|
if (!(resolvedExpandedKeys?.has(rk) ?? false)) return null;
|
|
1233
1344
|
let expandedRenderResult = null;
|
|
1234
1345
|
try {
|
|
1235
|
-
expandedRenderResult = expandable.expandedRowRender(
|
|
1346
|
+
expandedRenderResult = expandable.expandedRowRender(
|
|
1347
|
+
row,
|
|
1348
|
+
virtualRow.index,
|
|
1349
|
+
0,
|
|
1350
|
+
true
|
|
1351
|
+
);
|
|
1236
1352
|
} catch {
|
|
1237
1353
|
}
|
|
1238
1354
|
const expandedContent = /* @__PURE__ */ jsx4(
|
|
@@ -1600,7 +1716,16 @@ function BoltTable({
|
|
|
1600
1716
|
onCopy,
|
|
1601
1717
|
keepPinnedRowsAcrossPages,
|
|
1602
1718
|
onEdit,
|
|
1603
|
-
onRowClick
|
|
1719
|
+
onRowClick,
|
|
1720
|
+
enableColumnVirtualization = false,
|
|
1721
|
+
enableDynamicRowHeight = false,
|
|
1722
|
+
columnPersistence = false,
|
|
1723
|
+
showColumnSettings = true,
|
|
1724
|
+
hideGlobalSearch = false,
|
|
1725
|
+
globalSearchValue,
|
|
1726
|
+
onGlobalSearchChange,
|
|
1727
|
+
toolbarContent,
|
|
1728
|
+
columnSettingsLabel
|
|
1604
1729
|
}) {
|
|
1605
1730
|
const data = useMemo2(() => {
|
|
1606
1731
|
if (!Array.isArray(rawData)) return STABLE_EMPTY_DATA;
|
|
@@ -1608,7 +1733,8 @@ function BoltTable({
|
|
|
1608
1733
|
return filtered.length > 0 ? filtered : STABLE_EMPTY_DATA;
|
|
1609
1734
|
}, [rawData]);
|
|
1610
1735
|
const initialColumns = useMemo2(() => {
|
|
1611
|
-
if (!Array.isArray(rawInitialColumns))
|
|
1736
|
+
if (!Array.isArray(rawInitialColumns))
|
|
1737
|
+
return STABLE_EMPTY_COLS;
|
|
1612
1738
|
const safe = rawInitialColumns.filter(
|
|
1613
1739
|
(col) => col != null && typeof col.key === "string"
|
|
1614
1740
|
);
|
|
@@ -1673,6 +1799,106 @@ function BoltTable({
|
|
|
1673
1799
|
() => /* @__PURE__ */ new Map()
|
|
1674
1800
|
);
|
|
1675
1801
|
const manuallyResizedRef = useRef4(/* @__PURE__ */ new Set());
|
|
1802
|
+
const persistenceAppliedRef = useRef4(false);
|
|
1803
|
+
React4.useEffect(() => {
|
|
1804
|
+
if (!columnPersistence || persistenceAppliedRef.current) return;
|
|
1805
|
+
persistenceAppliedRef.current = true;
|
|
1806
|
+
const {
|
|
1807
|
+
storageKey,
|
|
1808
|
+
persistOrder = true,
|
|
1809
|
+
persistWidths = true,
|
|
1810
|
+
persistVisibility = true,
|
|
1811
|
+
persistPinned = true
|
|
1812
|
+
} = columnPersistence;
|
|
1813
|
+
try {
|
|
1814
|
+
const raw = localStorage.getItem(`bt_${storageKey}`);
|
|
1815
|
+
if (!raw) return;
|
|
1816
|
+
const saved = JSON.parse(raw);
|
|
1817
|
+
if (persistOrder && saved.order) {
|
|
1818
|
+
setColumnOrder(saved.order);
|
|
1819
|
+
}
|
|
1820
|
+
if (persistWidths && saved.widths) {
|
|
1821
|
+
setColumnWidths(
|
|
1822
|
+
new Map(Object.entries(saved.widths).map(([k, v]) => [k, Number(v)]))
|
|
1823
|
+
);
|
|
1824
|
+
}
|
|
1825
|
+
if (persistVisibility && saved.hidden || persistPinned && saved.pinned) {
|
|
1826
|
+
setColumns(
|
|
1827
|
+
(prev) => prev.map((col) => {
|
|
1828
|
+
let updated = col;
|
|
1829
|
+
if (persistVisibility && saved.hidden && col.key in saved.hidden) {
|
|
1830
|
+
updated = { ...updated, hidden: saved.hidden[col.key] };
|
|
1831
|
+
}
|
|
1832
|
+
if (persistPinned && saved.pinned && col.key in saved.pinned) {
|
|
1833
|
+
updated = { ...updated, pinned: saved.pinned[col.key] };
|
|
1834
|
+
}
|
|
1835
|
+
return updated;
|
|
1836
|
+
})
|
|
1837
|
+
);
|
|
1838
|
+
}
|
|
1839
|
+
} catch {
|
|
1840
|
+
}
|
|
1841
|
+
}, [columnPersistence]);
|
|
1842
|
+
const persistColumnsToStorage = useCallback2(() => {
|
|
1843
|
+
if (!columnPersistence) return;
|
|
1844
|
+
const {
|
|
1845
|
+
storageKey,
|
|
1846
|
+
persistOrder = true,
|
|
1847
|
+
persistWidths = true,
|
|
1848
|
+
persistVisibility = true,
|
|
1849
|
+
persistPinned = true
|
|
1850
|
+
} = columnPersistence;
|
|
1851
|
+
try {
|
|
1852
|
+
const saved = {};
|
|
1853
|
+
if (persistOrder) saved.order = columnOrder;
|
|
1854
|
+
if (persistWidths) {
|
|
1855
|
+
const widths = {};
|
|
1856
|
+
columnWidths.forEach((v, k) => {
|
|
1857
|
+
widths[k] = v;
|
|
1858
|
+
});
|
|
1859
|
+
saved.widths = widths;
|
|
1860
|
+
}
|
|
1861
|
+
if (persistVisibility) {
|
|
1862
|
+
const hidden = {};
|
|
1863
|
+
columns.forEach((c) => {
|
|
1864
|
+
if (c.hidden) hidden[c.key] = true;
|
|
1865
|
+
});
|
|
1866
|
+
saved.hidden = hidden;
|
|
1867
|
+
}
|
|
1868
|
+
if (persistPinned) {
|
|
1869
|
+
const pinned = {};
|
|
1870
|
+
columns.forEach((c) => {
|
|
1871
|
+
if (c.pinned) pinned[c.key] = c.pinned;
|
|
1872
|
+
});
|
|
1873
|
+
saved.pinned = pinned;
|
|
1874
|
+
}
|
|
1875
|
+
localStorage.setItem(`bt_${storageKey}`, JSON.stringify(saved));
|
|
1876
|
+
} catch {
|
|
1877
|
+
}
|
|
1878
|
+
}, [columnPersistence, columnOrder, columnWidths, columns]);
|
|
1879
|
+
React4.useEffect(() => {
|
|
1880
|
+
if (!columnPersistence || !persistenceAppliedRef.current) return;
|
|
1881
|
+
persistColumnsToStorage();
|
|
1882
|
+
}, [columnPersistence, persistColumnsToStorage]);
|
|
1883
|
+
const [showColumnPicker, setShowColumnPicker] = useState3(false);
|
|
1884
|
+
const columnPickerRef = useRef4(null);
|
|
1885
|
+
React4.useEffect(() => {
|
|
1886
|
+
if (!showColumnPicker) return;
|
|
1887
|
+
const close = (e) => {
|
|
1888
|
+
if (columnPickerRef.current && !columnPickerRef.current.contains(e.target)) {
|
|
1889
|
+
setShowColumnPicker(false);
|
|
1890
|
+
}
|
|
1891
|
+
};
|
|
1892
|
+
const onKey = (e) => {
|
|
1893
|
+
if (e.key === "Escape") setShowColumnPicker(false);
|
|
1894
|
+
};
|
|
1895
|
+
document.addEventListener("mousedown", close);
|
|
1896
|
+
document.addEventListener("keydown", onKey);
|
|
1897
|
+
return () => {
|
|
1898
|
+
document.removeEventListener("mousedown", close);
|
|
1899
|
+
document.removeEventListener("keydown", onKey);
|
|
1900
|
+
};
|
|
1901
|
+
}, [showColumnPicker]);
|
|
1676
1902
|
const columnsWithPersistedWidths = useMemo2(
|
|
1677
1903
|
() => columns.map((col) => ({
|
|
1678
1904
|
...col,
|
|
@@ -1737,6 +1963,32 @@ function BoltTable({
|
|
|
1737
1963
|
},
|
|
1738
1964
|
[rowKey]
|
|
1739
1965
|
);
|
|
1966
|
+
const deduplicatedRowKeys = useMemo2(() => {
|
|
1967
|
+
const seen = /* @__PURE__ */ new Map();
|
|
1968
|
+
return data.map((row, idx) => {
|
|
1969
|
+
const raw = getRowKey(row, idx);
|
|
1970
|
+
const count = seen.get(raw) ?? 0;
|
|
1971
|
+
seen.set(raw, count + 1);
|
|
1972
|
+
return count > 0 ? `${raw}__${idx}` : raw;
|
|
1973
|
+
});
|
|
1974
|
+
}, [data, getRowKey]);
|
|
1975
|
+
const hasDuplicateKeys = useMemo2(() => {
|
|
1976
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1977
|
+
for (const row of data) {
|
|
1978
|
+
if (row == null) continue;
|
|
1979
|
+
const k = getRowKey(row, 0);
|
|
1980
|
+
if (seen.has(k)) return true;
|
|
1981
|
+
seen.add(k);
|
|
1982
|
+
}
|
|
1983
|
+
return false;
|
|
1984
|
+
}, [data, getRowKey]);
|
|
1985
|
+
const getSafeRowKey = useCallback2(
|
|
1986
|
+
(record, index) => {
|
|
1987
|
+
if (!hasDuplicateKeys) return getRowKey(record, index);
|
|
1988
|
+
return deduplicatedRowKeys[index] ?? getRowKey(record, index);
|
|
1989
|
+
},
|
|
1990
|
+
[getRowKey, hasDuplicateKeys, deduplicatedRowKeys]
|
|
1991
|
+
);
|
|
1740
1992
|
const getRawRowKey = useCallback2(
|
|
1741
1993
|
(record, index) => {
|
|
1742
1994
|
if (record == null) return index;
|
|
@@ -1754,16 +2006,13 @@ function BoltTable({
|
|
|
1754
2006
|
},
|
|
1755
2007
|
[rowKey]
|
|
1756
2008
|
);
|
|
1757
|
-
const normalizedSelectedKeys = useMemo2(
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
);
|
|
1765
|
-
const getRowKeyRef = useRef4(getRowKey);
|
|
1766
|
-
getRowKeyRef.current = getRowKey;
|
|
2009
|
+
const normalizedSelectedKeys = useMemo2(() => {
|
|
2010
|
+
const keys = rowSelection?.selectedRowKeys;
|
|
2011
|
+
if (!Array.isArray(keys)) return [];
|
|
2012
|
+
return keys.filter((k) => k != null).map((k) => String(k));
|
|
2013
|
+
}, [rowSelection?.selectedRowKeys]);
|
|
2014
|
+
const getRowKeyRef = useRef4(getSafeRowKey);
|
|
2015
|
+
getRowKeyRef.current = getSafeRowKey;
|
|
1767
2016
|
const resolvedExpandedKeysRef = useRef4(resolvedExpandedKeys);
|
|
1768
2017
|
resolvedExpandedKeysRef.current = resolvedExpandedKeys;
|
|
1769
2018
|
const toggleExpandRef = useRef4(toggleExpand);
|
|
@@ -1946,7 +2195,9 @@ function BoltTable({
|
|
|
1946
2195
|
}
|
|
1947
2196
|
const scrollEl = tableAreaRef.current;
|
|
1948
2197
|
if (!scrollEl) return;
|
|
1949
|
-
const headers = scrollEl.querySelectorAll(
|
|
2198
|
+
const headers = scrollEl.querySelectorAll(
|
|
2199
|
+
"[data-bt-header][data-column-key]"
|
|
2200
|
+
);
|
|
1950
2201
|
let newOverId = null;
|
|
1951
2202
|
headers.forEach((h) => {
|
|
1952
2203
|
const key = h.dataset.columnKey;
|
|
@@ -1988,10 +2239,7 @@ function BoltTable({
|
|
|
1988
2239
|
const newIndex = items.indexOf(currentOverId);
|
|
1989
2240
|
if (oldIndex === -1 || newIndex === -1) return items;
|
|
1990
2241
|
const newOrder = arrayMove(items, oldIndex, newIndex);
|
|
1991
|
-
setTimeout(
|
|
1992
|
-
() => onColumnOrderChangeRef.current?.(newOrder),
|
|
1993
|
-
0
|
|
1994
|
-
);
|
|
2242
|
+
setTimeout(() => onColumnOrderChangeRef.current?.(newOrder), 0);
|
|
1995
2243
|
return newOrder;
|
|
1996
2244
|
});
|
|
1997
2245
|
});
|
|
@@ -2091,9 +2339,7 @@ function BoltTable({
|
|
|
2091
2339
|
[leftPinned, unpinned, rightPinned]
|
|
2092
2340
|
);
|
|
2093
2341
|
const freshOrderedColumns = useMemo2(() => {
|
|
2094
|
-
const latestMap = new Map(
|
|
2095
|
-
initialColumnsRef.current.map((c) => [c.key, c])
|
|
2096
|
-
);
|
|
2342
|
+
const latestMap = new Map(initialColumnsRef.current.map((c) => [c.key, c]));
|
|
2097
2343
|
return orderedColumns.map((col) => {
|
|
2098
2344
|
if (col.key === "__select__" || col.key === "__expand__") return col;
|
|
2099
2345
|
const latest = latestMap.get(col.key);
|
|
@@ -2132,6 +2378,11 @@ function BoltTable({
|
|
|
2132
2378
|
}
|
|
2133
2379
|
return offsets;
|
|
2134
2380
|
}, [leftPinned, rightPinned]);
|
|
2381
|
+
const columnGridIndexMap = useMemo2(() => {
|
|
2382
|
+
const map = /* @__PURE__ */ new Map();
|
|
2383
|
+
orderedColumns.forEach((col, i) => map.set(col.key, i + 1));
|
|
2384
|
+
return map;
|
|
2385
|
+
}, [orderedColumns]);
|
|
2135
2386
|
const handleTogglePin = (columnKey, pinned) => {
|
|
2136
2387
|
setColumns(
|
|
2137
2388
|
(prev) => prev.map((col) => col.key === columnKey ? { ...col, pinned } : col)
|
|
@@ -2150,22 +2401,27 @@ function BoltTable({
|
|
|
2150
2401
|
};
|
|
2151
2402
|
const [internalRowPinning, setInternalRowPinning] = useState3({ top: [], bottom: [] });
|
|
2152
2403
|
const resolvedRowPinning = rowPinning === true ? internalRowPinning : rowPinning && typeof rowPinning === "object" ? rowPinning : void 0;
|
|
2153
|
-
const handleRowPin = useCallback2(
|
|
2154
|
-
|
|
2155
|
-
onRowPin
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2404
|
+
const handleRowPin = useCallback2(
|
|
2405
|
+
(rk, pinned) => {
|
|
2406
|
+
if (onRowPin) {
|
|
2407
|
+
onRowPin(rk, pinned);
|
|
2408
|
+
return;
|
|
2409
|
+
}
|
|
2410
|
+
if (rowPinning === true) {
|
|
2411
|
+
setInternalRowPinning((prev) => {
|
|
2412
|
+
const rkStr = String(rk);
|
|
2413
|
+
const newTop = (prev.top ?? []).filter((k) => String(k) !== rkStr);
|
|
2414
|
+
const newBottom = (prev.bottom ?? []).filter(
|
|
2415
|
+
(k) => String(k) !== rkStr
|
|
2416
|
+
);
|
|
2417
|
+
if (pinned === "top") newTop.push(rk);
|
|
2418
|
+
else if (pinned === "bottom") newBottom.push(rk);
|
|
2419
|
+
return { top: newTop, bottom: newBottom };
|
|
2420
|
+
});
|
|
2421
|
+
}
|
|
2422
|
+
},
|
|
2423
|
+
[onRowPin, rowPinning]
|
|
2424
|
+
);
|
|
2169
2425
|
const onSortChangeRef = useRef4(onSortChange);
|
|
2170
2426
|
onSortChangeRef.current = onSortChange;
|
|
2171
2427
|
const [sortState, setSortState] = useState3({ key: "", direction: null });
|
|
@@ -2188,6 +2444,7 @@ function BoltTable({
|
|
|
2188
2444
|
const [columnFilters, setColumnFilters] = useState3(
|
|
2189
2445
|
{}
|
|
2190
2446
|
);
|
|
2447
|
+
const [internalGlobalSearch, setInternalGlobalSearch] = useState3("");
|
|
2191
2448
|
const handleColumnFilter = useCallback2(
|
|
2192
2449
|
(columnKey, value) => {
|
|
2193
2450
|
setColumnFilters((prev) => {
|
|
@@ -2212,6 +2469,20 @@ function BoltTable({
|
|
|
2212
2469
|
columnsLookupRef.current = initialColumns;
|
|
2213
2470
|
const processedData = useMemo2(() => {
|
|
2214
2471
|
let result = data;
|
|
2472
|
+
const globalSearch = globalSearchValue ?? internalGlobalSearch;
|
|
2473
|
+
if (globalSearch) {
|
|
2474
|
+
const searchLower = globalSearch.toLowerCase();
|
|
2475
|
+
result = result.filter((row) => {
|
|
2476
|
+
if (row == null) return false;
|
|
2477
|
+
for (const key of Object.keys(row)) {
|
|
2478
|
+
const val = row[key];
|
|
2479
|
+
if (val != null && String(val).toLowerCase().includes(searchLower)) {
|
|
2480
|
+
return true;
|
|
2481
|
+
}
|
|
2482
|
+
}
|
|
2483
|
+
return false;
|
|
2484
|
+
});
|
|
2485
|
+
}
|
|
2215
2486
|
if (!onFilterChangeRef.current) {
|
|
2216
2487
|
const filterKeys = Object.keys(columnFilters);
|
|
2217
2488
|
if (filterKeys.length > 0) {
|
|
@@ -2221,7 +2492,11 @@ function BoltTable({
|
|
|
2221
2492
|
try {
|
|
2222
2493
|
const col = columnsLookupRef.current.find((c) => c.key === key);
|
|
2223
2494
|
if (typeof col?.filterFn === "function") {
|
|
2224
|
-
return col.filterFn(
|
|
2495
|
+
return col.filterFn(
|
|
2496
|
+
columnFilters[key],
|
|
2497
|
+
row,
|
|
2498
|
+
col.dataIndex ?? key
|
|
2499
|
+
);
|
|
2225
2500
|
}
|
|
2226
2501
|
const cellVal = String(row[key] ?? "").toLowerCase();
|
|
2227
2502
|
return cellVal.includes(columnFilters[key].toLowerCase());
|
|
@@ -2264,7 +2539,7 @@ function BoltTable({
|
|
|
2264
2539
|
}
|
|
2265
2540
|
}
|
|
2266
2541
|
return result;
|
|
2267
|
-
}, [data, sortState, columnFilters]);
|
|
2542
|
+
}, [data, sortState, columnFilters, globalSearchValue, internalGlobalSearch]);
|
|
2268
2543
|
const pinnedRowCacheRef = useRef4(/* @__PURE__ */ new Map());
|
|
2269
2544
|
const { pinnedTopRows, pinnedBottomRows, unpinnedProcessedData } = useMemo2(() => {
|
|
2270
2545
|
if (!resolvedRowPinning || !resolvedRowPinning.top?.length && !resolvedRowPinning.bottom?.length) {
|
|
@@ -2276,19 +2551,23 @@ function BoltTable({
|
|
|
2276
2551
|
};
|
|
2277
2552
|
}
|
|
2278
2553
|
const topKeySet = new Set((resolvedRowPinning.top ?? []).map(String));
|
|
2279
|
-
const bottomKeySet = new Set(
|
|
2554
|
+
const bottomKeySet = new Set(
|
|
2555
|
+
(resolvedRowPinning.bottom ?? []).map(String)
|
|
2556
|
+
);
|
|
2280
2557
|
const topMap = /* @__PURE__ */ new Map();
|
|
2281
2558
|
const bottomMap = /* @__PURE__ */ new Map();
|
|
2282
2559
|
const rest = [];
|
|
2283
2560
|
processedData.forEach((row, idx) => {
|
|
2284
2561
|
if (row == null) return;
|
|
2285
|
-
const key =
|
|
2562
|
+
const key = getSafeRowKey(row, idx);
|
|
2286
2563
|
if (topKeySet.has(key)) {
|
|
2287
2564
|
topMap.set(key, row);
|
|
2288
|
-
if (keepPinnedRowsAcrossPages)
|
|
2565
|
+
if (keepPinnedRowsAcrossPages)
|
|
2566
|
+
pinnedRowCacheRef.current.set(key, row);
|
|
2289
2567
|
} else if (bottomKeySet.has(key)) {
|
|
2290
2568
|
bottomMap.set(key, row);
|
|
2291
|
-
if (keepPinnedRowsAcrossPages)
|
|
2569
|
+
if (keepPinnedRowsAcrossPages)
|
|
2570
|
+
pinnedRowCacheRef.current.set(key, row);
|
|
2292
2571
|
} else {
|
|
2293
2572
|
rest.push(row);
|
|
2294
2573
|
}
|
|
@@ -2306,7 +2585,8 @@ function BoltTable({
|
|
|
2306
2585
|
}
|
|
2307
2586
|
const allPinnedKeys = /* @__PURE__ */ new Set([...topKeySet, ...bottomKeySet]);
|
|
2308
2587
|
for (const cachedKey of pinnedRowCacheRef.current.keys()) {
|
|
2309
|
-
if (!allPinnedKeys.has(cachedKey))
|
|
2588
|
+
if (!allPinnedKeys.has(cachedKey))
|
|
2589
|
+
pinnedRowCacheRef.current.delete(cachedKey);
|
|
2310
2590
|
}
|
|
2311
2591
|
}
|
|
2312
2592
|
const orderedTop = (resolvedRowPinning.top ?? []).map((k) => topMap.get(String(k))).filter((r) => r !== void 0);
|
|
@@ -2316,7 +2596,12 @@ function BoltTable({
|
|
|
2316
2596
|
pinnedBottomRows: orderedBottom,
|
|
2317
2597
|
unpinnedProcessedData: rest
|
|
2318
2598
|
};
|
|
2319
|
-
}, [
|
|
2599
|
+
}, [
|
|
2600
|
+
processedData,
|
|
2601
|
+
resolvedRowPinning,
|
|
2602
|
+
getSafeRowKey,
|
|
2603
|
+
keepPinnedRowsAcrossPages
|
|
2604
|
+
]);
|
|
2320
2605
|
const pinnedTopHeight = pinnedTopRows.length * rowHeight;
|
|
2321
2606
|
const pinnedBottomHeight = pinnedBottomRows.length * rowHeight;
|
|
2322
2607
|
const pinnedTopKeySet = useMemo2(
|
|
@@ -2333,9 +2618,7 @@ function BoltTable({
|
|
|
2333
2618
|
}, []);
|
|
2334
2619
|
const [cellContextMenu, setCellContextMenu] = useState3(null);
|
|
2335
2620
|
const cellMenuRef = useRef4(null);
|
|
2336
|
-
const cellLongPressTimer = useRef4(
|
|
2337
|
-
null
|
|
2338
|
-
);
|
|
2621
|
+
const cellLongPressTimer = useRef4(null);
|
|
2339
2622
|
const cellTouchStart = useRef4(null);
|
|
2340
2623
|
const cancelCellLongPress = useCallback2(() => {
|
|
2341
2624
|
if (cellLongPressTimer.current) {
|
|
@@ -2362,10 +2645,11 @@ function BoltTable({
|
|
|
2362
2645
|
};
|
|
2363
2646
|
}, [cellContextMenu]);
|
|
2364
2647
|
const columnFiltersKey = Object.keys(columnFilters).sort().map((k) => `${k}:${columnFilters[k]}`).join("|");
|
|
2648
|
+
const activeGlobalSearch = globalSearchValue ?? internalGlobalSearch;
|
|
2365
2649
|
React4.useEffect(() => {
|
|
2366
2650
|
setInternalPage(1);
|
|
2367
2651
|
tableAreaRef.current?.scrollTo({ top: 0 });
|
|
2368
|
-
}, [columnFiltersKey]);
|
|
2652
|
+
}, [columnFiltersKey, activeGlobalSearch]);
|
|
2369
2653
|
const DEFAULT_PAGE_SIZE = 15;
|
|
2370
2654
|
const [internalPage, setInternalPage] = useState3(1);
|
|
2371
2655
|
const [internalPageSize, setInternalPageSize] = useState3(DEFAULT_PAGE_SIZE);
|
|
@@ -2411,6 +2695,17 @@ function BoltTable({
|
|
|
2411
2695
|
return paginatedData;
|
|
2412
2696
|
}, [shimmerData, infiniteLoadingShimmer, paginatedData]);
|
|
2413
2697
|
const measuredExpandedHeights = useRef4(/* @__PURE__ */ new Map());
|
|
2698
|
+
const measuredRowHeights = useRef4(/* @__PURE__ */ new Map());
|
|
2699
|
+
const handleRowHeightChange = useCallback2(
|
|
2700
|
+
(index, height) => {
|
|
2701
|
+
if (!enableDynamicRowHeight) return;
|
|
2702
|
+
const prev = measuredRowHeights.current.get(index);
|
|
2703
|
+
if (prev === height) return;
|
|
2704
|
+
measuredRowHeights.current.set(index, height);
|
|
2705
|
+
rowVirtualizerRef.current?.measure();
|
|
2706
|
+
},
|
|
2707
|
+
[enableDynamicRowHeight]
|
|
2708
|
+
);
|
|
2414
2709
|
const expandedRowMeasureRafRef = useRef4(null);
|
|
2415
2710
|
const handleExpandedRowResize = useCallback2(
|
|
2416
2711
|
(rk, contentHeight) => {
|
|
@@ -2435,23 +2730,73 @@ function BoltTable({
|
|
|
2435
2730
|
if (shimmerData) return rowHeight;
|
|
2436
2731
|
const item = displayData[index];
|
|
2437
2732
|
if (!item) return rowHeight;
|
|
2438
|
-
const
|
|
2439
|
-
|
|
2733
|
+
const baseHeight = enableDynamicRowHeight ? measuredRowHeights.current.get(index) ?? rowHeight : rowHeight;
|
|
2734
|
+
const key = getSafeRowKey(item, index);
|
|
2735
|
+
if (!resolvedExpandedKeys.has(key)) return baseHeight;
|
|
2440
2736
|
const cached = measuredExpandedHeights.current.get(key);
|
|
2441
|
-
return cached ?
|
|
2737
|
+
return cached ? baseHeight + cached : baseHeight + expandedRowHeight;
|
|
2442
2738
|
},
|
|
2443
2739
|
overscan: 5,
|
|
2444
2740
|
getItemKey: (index) => {
|
|
2445
2741
|
if (shimmerData) return `__shimmer_${index}__`;
|
|
2446
2742
|
const item = displayData[index];
|
|
2447
2743
|
if (!item) return `__fallback_${index}__`;
|
|
2448
|
-
return
|
|
2744
|
+
return getSafeRowKey(item, index);
|
|
2449
2745
|
},
|
|
2450
2746
|
paddingStart: pinnedTopHeight,
|
|
2451
2747
|
paddingEnd: pinnedBottomHeight
|
|
2452
2748
|
});
|
|
2453
2749
|
const rowVirtualizerRef = useRef4(rowVirtualizer);
|
|
2454
2750
|
rowVirtualizerRef.current = rowVirtualizer;
|
|
2751
|
+
const scrollLeftRef = useRef4(0);
|
|
2752
|
+
const [visibleColumnRange, setVisibleColumnRange] = useState3(null);
|
|
2753
|
+
React4.useEffect(() => {
|
|
2754
|
+
if (!enableColumnVirtualization) return;
|
|
2755
|
+
const el = tableAreaRef.current;
|
|
2756
|
+
if (!el) return;
|
|
2757
|
+
const updateVisibleColumns = () => {
|
|
2758
|
+
const scrollLeft = el.scrollLeft;
|
|
2759
|
+
scrollLeftRef.current = scrollLeft;
|
|
2760
|
+
const viewportWidth = el.clientWidth;
|
|
2761
|
+
const viewStart = scrollLeft;
|
|
2762
|
+
const viewEnd = scrollLeft + viewportWidth;
|
|
2763
|
+
let cumWidth = 0;
|
|
2764
|
+
let startIdx = -1;
|
|
2765
|
+
let endIdx = orderedColumns.length - 1;
|
|
2766
|
+
for (let i = 0; i < orderedColumns.length; i++) {
|
|
2767
|
+
const col = orderedColumns[i];
|
|
2768
|
+
const colWidth = col.width ?? 150;
|
|
2769
|
+
const colStart = cumWidth;
|
|
2770
|
+
const colEnd = cumWidth + colWidth;
|
|
2771
|
+
cumWidth = colEnd;
|
|
2772
|
+
if (col.pinned) continue;
|
|
2773
|
+
if (startIdx === -1 && colEnd > viewStart) {
|
|
2774
|
+
startIdx = Math.max(0, i - 1);
|
|
2775
|
+
}
|
|
2776
|
+
if (colStart > viewEnd) {
|
|
2777
|
+
endIdx = Math.min(orderedColumns.length - 1, i + 1);
|
|
2778
|
+
break;
|
|
2779
|
+
}
|
|
2780
|
+
}
|
|
2781
|
+
if (startIdx === -1) startIdx = 0;
|
|
2782
|
+
setVisibleColumnRange((prev) => {
|
|
2783
|
+
if (prev && prev.start === startIdx && prev.end === endIdx) return prev;
|
|
2784
|
+
return { start: startIdx, end: endIdx };
|
|
2785
|
+
});
|
|
2786
|
+
};
|
|
2787
|
+
updateVisibleColumns();
|
|
2788
|
+
el.addEventListener("scroll", updateVisibleColumns, { passive: true });
|
|
2789
|
+
return () => el.removeEventListener("scroll", updateVisibleColumns);
|
|
2790
|
+
}, [enableColumnVirtualization, orderedColumns]);
|
|
2791
|
+
const virtualizedColumns = useMemo2(() => {
|
|
2792
|
+
if (!enableColumnVirtualization || !visibleColumnRange)
|
|
2793
|
+
return freshOrderedColumns;
|
|
2794
|
+
return freshOrderedColumns.filter((col, idx) => {
|
|
2795
|
+
if (col.pinned) return true;
|
|
2796
|
+
if (col.key === "__select__" || col.key === "__expand__") return true;
|
|
2797
|
+
return idx >= visibleColumnRange.start && idx <= visibleColumnRange.end;
|
|
2798
|
+
});
|
|
2799
|
+
}, [enableColumnVirtualization, visibleColumnRange, freshOrderedColumns]);
|
|
2455
2800
|
const resolvedExpandedKeysFingerprint = Array.from(resolvedExpandedKeys).sort().join(",");
|
|
2456
2801
|
React4.useLayoutEffect(() => {
|
|
2457
2802
|
rowVirtualizer.measure();
|
|
@@ -2518,7 +2863,10 @@ function BoltTable({
|
|
|
2518
2863
|
}, [pgCurrent, needsClientPagination]);
|
|
2519
2864
|
const getPageNumbers = () => {
|
|
2520
2865
|
if (totalPages <= 7)
|
|
2521
|
-
return Array.from(
|
|
2866
|
+
return Array.from(
|
|
2867
|
+
{ length: totalPages },
|
|
2868
|
+
(_, i) => i + 1
|
|
2869
|
+
);
|
|
2522
2870
|
const leftSibling = Math.max(currentPage - 1, 2);
|
|
2523
2871
|
const showLeftEllipsis = leftSibling > 2;
|
|
2524
2872
|
const rightSibling = Math.min(currentPage + 1, totalPages - 1);
|
|
@@ -2529,7 +2877,10 @@ function BoltTable({
|
|
|
2529
2877
|
return [
|
|
2530
2878
|
1,
|
|
2531
2879
|
"ellipsis-left",
|
|
2532
|
-
...Array.from(
|
|
2880
|
+
...Array.from(
|
|
2881
|
+
{ length: 5 },
|
|
2882
|
+
(_, i) => totalPages - 4 + i
|
|
2883
|
+
)
|
|
2533
2884
|
];
|
|
2534
2885
|
return [
|
|
2535
2886
|
1,
|
|
@@ -2600,6 +2951,190 @@ function BoltTable({
|
|
|
2600
2951
|
}
|
|
2601
2952
|
${onRowClick ? "[data-bt-cell] { cursor: pointer; }" : ""}
|
|
2602
2953
|
` }),
|
|
2954
|
+
(!hideGlobalSearch || showColumnSettings) && /* @__PURE__ */ jsxs5(
|
|
2955
|
+
"div",
|
|
2956
|
+
{
|
|
2957
|
+
style: {
|
|
2958
|
+
display: "flex",
|
|
2959
|
+
alignItems: "center",
|
|
2960
|
+
gap: 8,
|
|
2961
|
+
padding: "6px 8px",
|
|
2962
|
+
borderBottom: "1px solid rgba(128,128,128,0.2)",
|
|
2963
|
+
fontSize: 12,
|
|
2964
|
+
flexShrink: 0
|
|
2965
|
+
},
|
|
2966
|
+
children: [
|
|
2967
|
+
!hideGlobalSearch && /* @__PURE__ */ jsxs5(
|
|
2968
|
+
"div",
|
|
2969
|
+
{
|
|
2970
|
+
style: {
|
|
2971
|
+
display: "flex",
|
|
2972
|
+
alignItems: "center",
|
|
2973
|
+
gap: 4,
|
|
2974
|
+
flex: "1 1 0%",
|
|
2975
|
+
position: "relative"
|
|
2976
|
+
},
|
|
2977
|
+
children: [
|
|
2978
|
+
/* @__PURE__ */ jsx5(
|
|
2979
|
+
"span",
|
|
2980
|
+
{
|
|
2981
|
+
style: { display: "flex", color: "GrayText", flexShrink: 0 },
|
|
2982
|
+
children: icons?.search ?? /* @__PURE__ */ jsx5(SearchIcon, { style: { width: 14, height: 14 } })
|
|
2983
|
+
}
|
|
2984
|
+
),
|
|
2985
|
+
/* @__PURE__ */ jsx5(
|
|
2986
|
+
"input",
|
|
2987
|
+
{
|
|
2988
|
+
type: "text",
|
|
2989
|
+
placeholder: "Search all columns...",
|
|
2990
|
+
value: globalSearchValue ?? internalGlobalSearch,
|
|
2991
|
+
onChange: (e) => {
|
|
2992
|
+
const v = e.target.value;
|
|
2993
|
+
if (onGlobalSearchChange) onGlobalSearchChange(v);
|
|
2994
|
+
else setInternalGlobalSearch(v);
|
|
2995
|
+
},
|
|
2996
|
+
style: {
|
|
2997
|
+
flex: "1 1 0%",
|
|
2998
|
+
border: "none",
|
|
2999
|
+
outline: "none",
|
|
3000
|
+
background: "transparent",
|
|
3001
|
+
font: "inherit",
|
|
3002
|
+
color: "inherit",
|
|
3003
|
+
padding: "4px 6px",
|
|
3004
|
+
minWidth: 0
|
|
3005
|
+
}
|
|
3006
|
+
}
|
|
3007
|
+
),
|
|
3008
|
+
(globalSearchValue ?? internalGlobalSearch) && /* @__PURE__ */ jsx5(
|
|
3009
|
+
"button",
|
|
3010
|
+
{
|
|
3011
|
+
type: "button",
|
|
3012
|
+
onClick: () => {
|
|
3013
|
+
if (onGlobalSearchChange) onGlobalSearchChange("");
|
|
3014
|
+
else setInternalGlobalSearch("");
|
|
3015
|
+
},
|
|
3016
|
+
style: {
|
|
3017
|
+
display: "flex",
|
|
3018
|
+
alignItems: "center",
|
|
3019
|
+
justifyContent: "center",
|
|
3020
|
+
background: "none",
|
|
3021
|
+
border: "none",
|
|
3022
|
+
cursor: "pointer",
|
|
3023
|
+
padding: 2,
|
|
3024
|
+
color: "GrayText",
|
|
3025
|
+
flexShrink: 0
|
|
3026
|
+
},
|
|
3027
|
+
children: icons?.close ?? /* @__PURE__ */ jsx5(XIcon, { style: { width: 12, height: 12 } })
|
|
3028
|
+
}
|
|
3029
|
+
)
|
|
3030
|
+
]
|
|
3031
|
+
}
|
|
3032
|
+
),
|
|
3033
|
+
toolbarContent,
|
|
3034
|
+
showColumnSettings && /* @__PURE__ */ jsxs5("div", { style: { position: "relative", flexShrink: 0 }, children: [
|
|
3035
|
+
/* @__PURE__ */ jsxs5(
|
|
3036
|
+
"button",
|
|
3037
|
+
{
|
|
3038
|
+
type: "button",
|
|
3039
|
+
onClick: () => setShowColumnPicker((p) => !p),
|
|
3040
|
+
style: {
|
|
3041
|
+
display: "flex",
|
|
3042
|
+
alignItems: "center",
|
|
3043
|
+
justifyContent: "center",
|
|
3044
|
+
background: "none",
|
|
3045
|
+
border: "1px solid rgba(128,128,128,0.2)",
|
|
3046
|
+
borderRadius: 4,
|
|
3047
|
+
cursor: "pointer",
|
|
3048
|
+
padding: "4px 6px",
|
|
3049
|
+
color: "inherit",
|
|
3050
|
+
gap: 4,
|
|
3051
|
+
fontSize: 12
|
|
3052
|
+
},
|
|
3053
|
+
title: "Column settings",
|
|
3054
|
+
children: [
|
|
3055
|
+
icons?.columns ?? /* @__PURE__ */ jsx5(ColumnsIcon, { style: { width: 14, height: 14 } }),
|
|
3056
|
+
/* @__PURE__ */ jsx5("span", { children: columnSettingsLabel ?? "Columns" })
|
|
3057
|
+
]
|
|
3058
|
+
}
|
|
3059
|
+
),
|
|
3060
|
+
showColumnPicker && /* @__PURE__ */ jsx5(
|
|
3061
|
+
"div",
|
|
3062
|
+
{
|
|
3063
|
+
ref: columnPickerRef,
|
|
3064
|
+
style: {
|
|
3065
|
+
position: "absolute",
|
|
3066
|
+
top: "100%",
|
|
3067
|
+
right: 0,
|
|
3068
|
+
zIndex: 99999,
|
|
3069
|
+
minWidth: 200,
|
|
3070
|
+
maxHeight: 320,
|
|
3071
|
+
overflowY: "auto",
|
|
3072
|
+
borderRadius: 8,
|
|
3073
|
+
border: "1px solid rgba(128,128,128,0.2)",
|
|
3074
|
+
boxShadow: "0 4px 24px rgba(0,0,0,0.12)",
|
|
3075
|
+
backdropFilter: "blur(16px)",
|
|
3076
|
+
WebkitBackdropFilter: "blur(16px)",
|
|
3077
|
+
backgroundColor: "rgba(128,128,128,0.08)",
|
|
3078
|
+
padding: "4px 0",
|
|
3079
|
+
marginTop: 4
|
|
3080
|
+
},
|
|
3081
|
+
children: initialColumns.filter(
|
|
3082
|
+
(c) => c.key !== "__select__" && c.key !== "__expand__"
|
|
3083
|
+
).map((col) => {
|
|
3084
|
+
const current = columns.find((c) => c.key === col.key);
|
|
3085
|
+
const isHidden = current?.hidden ?? false;
|
|
3086
|
+
const isPinned = !!current?.pinned;
|
|
3087
|
+
return /* @__PURE__ */ jsxs5(
|
|
3088
|
+
"label",
|
|
3089
|
+
{
|
|
3090
|
+
style: {
|
|
3091
|
+
display: "flex",
|
|
3092
|
+
alignItems: "center",
|
|
3093
|
+
gap: 8,
|
|
3094
|
+
padding: "6px 12px",
|
|
3095
|
+
cursor: isPinned ? "not-allowed" : "pointer",
|
|
3096
|
+
opacity: isPinned ? 0.5 : 1,
|
|
3097
|
+
fontSize: 12
|
|
3098
|
+
},
|
|
3099
|
+
children: [
|
|
3100
|
+
/* @__PURE__ */ jsx5(
|
|
3101
|
+
"input",
|
|
3102
|
+
{
|
|
3103
|
+
type: "checkbox",
|
|
3104
|
+
checked: !isHidden,
|
|
3105
|
+
disabled: isPinned,
|
|
3106
|
+
onChange: () => {
|
|
3107
|
+
if (isPinned) return;
|
|
3108
|
+
handleToggleHide(col.key);
|
|
3109
|
+
},
|
|
3110
|
+
style: {
|
|
3111
|
+
cursor: isPinned ? "not-allowed" : "pointer",
|
|
3112
|
+
accentColor
|
|
3113
|
+
}
|
|
3114
|
+
}
|
|
3115
|
+
),
|
|
3116
|
+
/* @__PURE__ */ jsx5(
|
|
3117
|
+
"span",
|
|
3118
|
+
{
|
|
3119
|
+
style: {
|
|
3120
|
+
overflow: "hidden",
|
|
3121
|
+
textOverflow: "ellipsis",
|
|
3122
|
+
whiteSpace: "nowrap"
|
|
3123
|
+
},
|
|
3124
|
+
children: typeof col.title === "string" ? col.title : col.key
|
|
3125
|
+
}
|
|
3126
|
+
)
|
|
3127
|
+
]
|
|
3128
|
+
},
|
|
3129
|
+
col.key
|
|
3130
|
+
);
|
|
3131
|
+
})
|
|
3132
|
+
}
|
|
3133
|
+
)
|
|
3134
|
+
] })
|
|
3135
|
+
]
|
|
3136
|
+
}
|
|
3137
|
+
),
|
|
2603
3138
|
/* @__PURE__ */ jsx5(
|
|
2604
3139
|
"div",
|
|
2605
3140
|
{
|
|
@@ -2744,19 +3279,20 @@ function BoltTable({
|
|
|
2744
3279
|
...isEmpty ? { height: "100%" } : {}
|
|
2745
3280
|
},
|
|
2746
3281
|
onContextMenu: (e) => {
|
|
2747
|
-
const cell = e.target.closest(
|
|
3282
|
+
const cell = e.target.closest(
|
|
3283
|
+
"[data-bt-cell]"
|
|
3284
|
+
);
|
|
2748
3285
|
if (!cell) return;
|
|
2749
3286
|
const rk = cell.dataset.rowKey;
|
|
2750
3287
|
const ck = cell.dataset.columnKey;
|
|
2751
3288
|
if (!rk || !ck) return;
|
|
2752
|
-
const col = freshOrderedColumns.find(
|
|
2753
|
-
(c) => c.key === ck
|
|
2754
|
-
);
|
|
3289
|
+
const col = freshOrderedColumns.find((c) => c.key === ck);
|
|
2755
3290
|
const hasCopy = !!col?.copy;
|
|
2756
3291
|
const hasRowPin = !!rowPinning;
|
|
2757
3292
|
const hasCellItems = col?.columnCellContextMenuItems && col.columnCellContextMenuItems.length > 0;
|
|
2758
3293
|
const hasEdit = !!col?.editable && !col?.render && !!onEdit;
|
|
2759
|
-
if (!hasCopy && !hasRowPin && !hasCellItems && !hasEdit)
|
|
3294
|
+
if (!hasCopy && !hasRowPin && !hasCellItems && !hasEdit)
|
|
3295
|
+
return;
|
|
2760
3296
|
e.preventDefault();
|
|
2761
3297
|
setCellContextMenu({
|
|
2762
3298
|
x: Math.min(e.clientX, window.innerWidth - 200),
|
|
@@ -2767,7 +3303,9 @@ function BoltTable({
|
|
|
2767
3303
|
},
|
|
2768
3304
|
onTouchStart: (e) => {
|
|
2769
3305
|
cancelCellLongPress();
|
|
2770
|
-
const cell = e.target.closest(
|
|
3306
|
+
const cell = e.target.closest(
|
|
3307
|
+
"[data-bt-cell]"
|
|
3308
|
+
);
|
|
2771
3309
|
if (!cell) return;
|
|
2772
3310
|
const touch = e.touches[0];
|
|
2773
3311
|
cellTouchStart.current = {
|
|
@@ -2779,14 +3317,13 @@ function BoltTable({
|
|
|
2779
3317
|
cellLongPressTimer.current = setTimeout(() => {
|
|
2780
3318
|
cellLongPressTimer.current = null;
|
|
2781
3319
|
if (!rk || !ck) return;
|
|
2782
|
-
const col = freshOrderedColumns.find(
|
|
2783
|
-
(c) => c.key === ck
|
|
2784
|
-
);
|
|
3320
|
+
const col = freshOrderedColumns.find((c) => c.key === ck);
|
|
2785
3321
|
const hasCopy = !!col?.copy;
|
|
2786
3322
|
const hasRowPin = !!rowPinning;
|
|
2787
3323
|
const hasCellItems = col?.columnCellContextMenuItems && col.columnCellContextMenuItems.length > 0;
|
|
2788
3324
|
const hasEdit = !!col?.editable && !col?.render && !!onEdit;
|
|
2789
|
-
if (!hasCopy && !hasRowPin && !hasCellItems && !hasEdit)
|
|
3325
|
+
if (!hasCopy && !hasRowPin && !hasCellItems && !hasEdit)
|
|
3326
|
+
return;
|
|
2790
3327
|
setCellContextMenu({
|
|
2791
3328
|
x: Math.min(touch.clientX, window.innerWidth - 200),
|
|
2792
3329
|
y: Math.min(touch.clientY, window.innerHeight - 200),
|
|
@@ -2807,7 +3344,8 @@ function BoltTable({
|
|
|
2807
3344
|
onTouchCancel: cancelCellLongPress,
|
|
2808
3345
|
onClick: onRowClick ? (e) => {
|
|
2809
3346
|
const target = e.target;
|
|
2810
|
-
if (target.closest("input, button, a, select, textarea"))
|
|
3347
|
+
if (target.closest("input, button, a, select, textarea"))
|
|
3348
|
+
return;
|
|
2811
3349
|
const cell = target.closest("[data-bt-cell]");
|
|
2812
3350
|
if (!cell) return;
|
|
2813
3351
|
const rk = cell.dataset.rowKey;
|
|
@@ -2815,21 +3353,21 @@ function BoltTable({
|
|
|
2815
3353
|
for (let i = 0; i < displayData.length; i++) {
|
|
2816
3354
|
const row = displayData[i];
|
|
2817
3355
|
if (row == null) continue;
|
|
2818
|
-
if (
|
|
3356
|
+
if (getSafeRowKey(row, i) === rk) {
|
|
2819
3357
|
onRowClick(row, i, e);
|
|
2820
3358
|
return;
|
|
2821
3359
|
}
|
|
2822
3360
|
}
|
|
2823
3361
|
for (let i = 0; i < pinnedTopRows.length; i++) {
|
|
2824
3362
|
if (pinnedTopRows[i] == null) continue;
|
|
2825
|
-
if (
|
|
3363
|
+
if (getSafeRowKey(pinnedTopRows[i], i) === rk) {
|
|
2826
3364
|
onRowClick(pinnedTopRows[i], i, e);
|
|
2827
3365
|
return;
|
|
2828
3366
|
}
|
|
2829
3367
|
}
|
|
2830
3368
|
for (let i = 0; i < pinnedBottomRows.length; i++) {
|
|
2831
3369
|
if (pinnedBottomRows[i] == null) continue;
|
|
2832
|
-
if (
|
|
3370
|
+
if (getSafeRowKey(pinnedBottomRows[i], i) === rk) {
|
|
2833
3371
|
onRowClick(pinnedBottomRows[i], i, e);
|
|
2834
3372
|
return;
|
|
2835
3373
|
}
|
|
@@ -2939,7 +3477,11 @@ function BoltTable({
|
|
|
2939
3477
|
});
|
|
2940
3478
|
}
|
|
2941
3479
|
},
|
|
2942
|
-
style: {
|
|
3480
|
+
style: {
|
|
3481
|
+
cursor: "pointer",
|
|
3482
|
+
accentColor,
|
|
3483
|
+
backgroundColor: "#94A3B8"
|
|
3484
|
+
}
|
|
2943
3485
|
}
|
|
2944
3486
|
)
|
|
2945
3487
|
},
|
|
@@ -2999,7 +3541,10 @@ function BoltTable({
|
|
|
2999
3541
|
filterValue: columnFilters[column.key] ?? "",
|
|
3000
3542
|
onFilter: handleColumnFilter,
|
|
3001
3543
|
onClearFilter: handleClearFilter,
|
|
3002
|
-
customContextMenuItems: column.columnHeaderContextMenuItems ? [
|
|
3544
|
+
customContextMenuItems: column.columnHeaderContextMenuItems ? [
|
|
3545
|
+
...columnContextMenuItems ?? [],
|
|
3546
|
+
...column.columnHeaderContextMenuItems
|
|
3547
|
+
] : columnContextMenuItems,
|
|
3003
3548
|
disabledFilters,
|
|
3004
3549
|
headerGridRow: leafGridRow,
|
|
3005
3550
|
headerHeight: leafHeight,
|
|
@@ -3051,14 +3596,14 @@ function BoltTable({
|
|
|
3051
3596
|
TableBody_default,
|
|
3052
3597
|
{
|
|
3053
3598
|
data: displayData,
|
|
3054
|
-
orderedColumns:
|
|
3599
|
+
orderedColumns: virtualizedColumns,
|
|
3055
3600
|
rowVirtualizer,
|
|
3056
3601
|
columnOffsets,
|
|
3057
3602
|
styles,
|
|
3058
3603
|
classNames,
|
|
3059
3604
|
rowSelection: !showShimmer ? rowSelection : void 0,
|
|
3060
3605
|
normalizedSelectedKeys,
|
|
3061
|
-
getRowKey,
|
|
3606
|
+
getRowKey: getSafeRowKey,
|
|
3062
3607
|
getRawRowKey,
|
|
3063
3608
|
expandable: !showShimmer ? expandable : void 0,
|
|
3064
3609
|
resolvedExpandedKeys,
|
|
@@ -3079,7 +3624,10 @@ function BoltTable({
|
|
|
3079
3624
|
bodyGridRow: hasColumnGroups ? 3 : 2,
|
|
3080
3625
|
onEdit,
|
|
3081
3626
|
editingCell,
|
|
3082
|
-
onEditComplete: handleEditComplete
|
|
3627
|
+
onEditComplete: handleEditComplete,
|
|
3628
|
+
enableDynamicRowHeight,
|
|
3629
|
+
onRowHeightChange: handleRowHeightChange,
|
|
3630
|
+
columnGridIndexMap
|
|
3083
3631
|
}
|
|
3084
3632
|
)
|
|
3085
3633
|
]
|
|
@@ -3109,39 +3657,53 @@ function BoltTable({
|
|
|
3109
3657
|
...styles.pagination
|
|
3110
3658
|
},
|
|
3111
3659
|
children: [
|
|
3112
|
-
/* @__PURE__ */ jsx5(
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
"
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3660
|
+
/* @__PURE__ */ jsx5(
|
|
3661
|
+
"div",
|
|
3662
|
+
{
|
|
3663
|
+
style: { display: "flex", flex: "1 1 0%", alignItems: "center" },
|
|
3664
|
+
children: (() => {
|
|
3665
|
+
const rangeStart = total > 0 ? (currentPage - 1) * pageSize + 1 : 0;
|
|
3666
|
+
const rangeEnd = Math.min(currentPage * pageSize, total);
|
|
3667
|
+
return typeof pagination === "object" && pagination?.showTotal ? /* @__PURE__ */ jsxs5(
|
|
3668
|
+
"span",
|
|
3669
|
+
{
|
|
3670
|
+
className: classNames.paginationInfo ?? "",
|
|
3671
|
+
style: {
|
|
3672
|
+
color: "GrayText",
|
|
3673
|
+
fontSize: 12,
|
|
3674
|
+
...styles.paginationInfo
|
|
3675
|
+
},
|
|
3676
|
+
children: [
|
|
3677
|
+
"Showing",
|
|
3678
|
+
" ",
|
|
3679
|
+
pagination.showTotal(total, [rangeStart, rangeEnd]),
|
|
3680
|
+
" of",
|
|
3681
|
+
" ",
|
|
3682
|
+
total,
|
|
3683
|
+
" items"
|
|
3684
|
+
]
|
|
3685
|
+
}
|
|
3686
|
+
) : /* @__PURE__ */ jsxs5(
|
|
3687
|
+
"span",
|
|
3688
|
+
{
|
|
3689
|
+
className: classNames.paginationInfo ?? "",
|
|
3690
|
+
style: {
|
|
3691
|
+
color: "GrayText",
|
|
3692
|
+
fontSize: 12,
|
|
3693
|
+
...styles.paginationInfo
|
|
3694
|
+
},
|
|
3695
|
+
children: [
|
|
3696
|
+
rangeStart,
|
|
3697
|
+
"\u2013",
|
|
3698
|
+
rangeEnd,
|
|
3699
|
+
" of ",
|
|
3700
|
+
total
|
|
3701
|
+
]
|
|
3702
|
+
}
|
|
3703
|
+
);
|
|
3704
|
+
})()
|
|
3705
|
+
}
|
|
3706
|
+
),
|
|
3145
3707
|
/* @__PURE__ */ jsxs5(
|
|
3146
3708
|
"div",
|
|
3147
3709
|
{
|
|
@@ -3424,9 +3986,7 @@ function BoltTable({
|
|
|
3424
3986
|
(c) => c.key === cellContextMenu.columnKey
|
|
3425
3987
|
);
|
|
3426
3988
|
const isPinnedTop = pinnedTopKeySet.has(cellContextMenu.rowKey);
|
|
3427
|
-
const isPinnedBottom = pinnedBottomKeySet.has(
|
|
3428
|
-
cellContextMenu.rowKey
|
|
3429
|
-
);
|
|
3989
|
+
const isPinnedBottom = pinnedBottomKeySet.has(cellContextMenu.rowKey);
|
|
3430
3990
|
const hasCopy = !!menuCol?.copy;
|
|
3431
3991
|
const hasRowPin = !!rowPinning;
|
|
3432
3992
|
const hasEdit = !!menuCol?.editable && !menuCol?.render && !!onEdit;
|
|
@@ -3439,7 +3999,7 @@ function BoltTable({
|
|
|
3439
3999
|
];
|
|
3440
4000
|
for (let i = 0; i < allRows.length; i++) {
|
|
3441
4001
|
if (allRows[i] == null) continue;
|
|
3442
|
-
const rk =
|
|
4002
|
+
const rk = getSafeRowKey(allRows[i], i);
|
|
3443
4003
|
if (rk === cellContextMenu.rowKey) {
|
|
3444
4004
|
menuRecord = allRows[i];
|
|
3445
4005
|
menuRowIndex = i;
|
|
@@ -3641,7 +4201,20 @@ function BoltTable({
|
|
|
3641
4201
|
setCellContextMenu(null);
|
|
3642
4202
|
},
|
|
3643
4203
|
children: [
|
|
3644
|
-
item.icon && /* @__PURE__ */ jsx5(
|
|
4204
|
+
item.icon && /* @__PURE__ */ jsx5(
|
|
4205
|
+
"span",
|
|
4206
|
+
{
|
|
4207
|
+
style: {
|
|
4208
|
+
display: "flex",
|
|
4209
|
+
width: 14,
|
|
4210
|
+
height: 14,
|
|
4211
|
+
alignItems: "center",
|
|
4212
|
+
justifyContent: "center",
|
|
4213
|
+
flexShrink: 0
|
|
4214
|
+
},
|
|
4215
|
+
children: item.icon
|
|
4216
|
+
}
|
|
4217
|
+
),
|
|
3645
4218
|
item.label
|
|
3646
4219
|
]
|
|
3647
4220
|
},
|