bolt-table 0.1.19 → 0.1.21
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/dist/index.d.mts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +241 -96
- package/dist/index.mjs +241 -96
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -872,6 +872,7 @@ var Cell = import_react3.default.memo(
|
|
|
872
872
|
rowKey,
|
|
873
873
|
allData,
|
|
874
874
|
getRowKey,
|
|
875
|
+
getRawRowKey,
|
|
875
876
|
accentColor,
|
|
876
877
|
isLoading
|
|
877
878
|
}) => {
|
|
@@ -914,6 +915,7 @@ var Cell = import_react3.default.memo(
|
|
|
914
915
|
const checkboxProps = rowSelection.getCheckboxProps?.(record) ?? {
|
|
915
916
|
disabled: false
|
|
916
917
|
};
|
|
918
|
+
const rawKey = getRawRowKey ? getRawRowKey(record, rowIndex) : rowKey;
|
|
917
919
|
const content2 = rowSelection.type === "radio" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
918
920
|
"input",
|
|
919
921
|
{
|
|
@@ -923,7 +925,7 @@ var Cell = import_react3.default.memo(
|
|
|
923
925
|
onChange: (e) => {
|
|
924
926
|
e.stopPropagation();
|
|
925
927
|
rowSelection.onSelect?.(record, true, [record], e.nativeEvent);
|
|
926
|
-
rowSelection.onChange?.([
|
|
928
|
+
rowSelection.onChange?.([rawKey], [record], { type: "single" });
|
|
927
929
|
},
|
|
928
930
|
style: { cursor: "pointer", accentColor }
|
|
929
931
|
}
|
|
@@ -935,15 +937,12 @@ var Cell = import_react3.default.memo(
|
|
|
935
937
|
disabled: checkboxProps.disabled,
|
|
936
938
|
onChange: (e) => {
|
|
937
939
|
e.stopPropagation();
|
|
938
|
-
const currentKeys =
|
|
939
|
-
|
|
940
|
-
)
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
getRowKey ? getRowKey(row, idx) : String(idx)
|
|
945
|
-
)
|
|
946
|
-
);
|
|
940
|
+
const currentKeys = rowSelection.selectedRowKeys ?? [];
|
|
941
|
+
const newSelected = isSelected ? currentKeys.filter((k) => String(k) !== rowKey) : [...currentKeys, rawKey];
|
|
942
|
+
const newSelectedRows = (allData ?? []).filter((row, idx) => {
|
|
943
|
+
const rk = getRowKey ? getRowKey(row, idx) : String(idx);
|
|
944
|
+
return newSelected.some((k) => String(k) === rk);
|
|
945
|
+
});
|
|
947
946
|
rowSelection.onSelect?.(
|
|
948
947
|
record,
|
|
949
948
|
!isSelected,
|
|
@@ -979,7 +978,16 @@ var Cell = import_react3.default.memo(
|
|
|
979
978
|
}
|
|
980
979
|
);
|
|
981
980
|
}
|
|
982
|
-
|
|
981
|
+
let content;
|
|
982
|
+
if (column.render) {
|
|
983
|
+
try {
|
|
984
|
+
content = column.render(value, record, rowIndex);
|
|
985
|
+
} catch {
|
|
986
|
+
content = String(value ?? "");
|
|
987
|
+
}
|
|
988
|
+
} else {
|
|
989
|
+
content = value ?? "";
|
|
990
|
+
}
|
|
983
991
|
const isSystem = column.key === "__select__" || column.key === "__expand__";
|
|
984
992
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
985
993
|
"div",
|
|
@@ -1073,6 +1081,7 @@ var TableBody = ({
|
|
|
1073
1081
|
rowSelection,
|
|
1074
1082
|
normalizedSelectedKeys = [],
|
|
1075
1083
|
getRowKey,
|
|
1084
|
+
getRawRowKey,
|
|
1076
1085
|
expandable,
|
|
1077
1086
|
resolvedExpandedKeys,
|
|
1078
1087
|
rowHeight = 40,
|
|
@@ -1092,14 +1101,16 @@ var TableBody = ({
|
|
|
1092
1101
|
const virtualItems = rowVirtualizer.getVirtualItems();
|
|
1093
1102
|
const totalSize = rowVirtualizer.getTotalSize();
|
|
1094
1103
|
const selectedKeySet = (0, import_react3.useMemo)(() => new Set(normalizedSelectedKeys), [normalizedSelectedKeys]);
|
|
1104
|
+
const safeData = data ?? [];
|
|
1105
|
+
const safeColumns = orderedColumns ?? [];
|
|
1095
1106
|
const allDataForSelection = (0, import_react3.useMemo)(() => {
|
|
1096
1107
|
if (pinnedTopData.length === 0 && pinnedBottomData.length === 0)
|
|
1097
|
-
return
|
|
1098
|
-
return [...pinnedTopData, ...
|
|
1099
|
-
}, [pinnedTopData,
|
|
1108
|
+
return safeData;
|
|
1109
|
+
return [...pinnedTopData, ...safeData, ...pinnedBottomData];
|
|
1110
|
+
}, [pinnedTopData, safeData, pinnedBottomData]);
|
|
1100
1111
|
const pinnedRowBg = styles?.pinnedRowBg ?? styles?.pinnedBg;
|
|
1101
1112
|
const columnStyles = (0, import_react3.useMemo)(() => {
|
|
1102
|
-
return
|
|
1113
|
+
return safeColumns.map((col, colIndex) => {
|
|
1103
1114
|
const stickyOffset = columnOffsets.get(col.key);
|
|
1104
1115
|
const isPinned = Boolean(col.pinned);
|
|
1105
1116
|
let zIndex = 0;
|
|
@@ -1121,10 +1132,12 @@ var TableBody = ({
|
|
|
1121
1132
|
}
|
|
1122
1133
|
return { key: col.key, style, isPinned };
|
|
1123
1134
|
});
|
|
1124
|
-
}, [
|
|
1135
|
+
}, [safeColumns, columnOffsets, totalSize, styles]);
|
|
1136
|
+
if (safeData.length === 0 || safeColumns.length === 0) return null;
|
|
1125
1137
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
1126
1138
|
columnStyles.map((colStyle, colIndex) => {
|
|
1127
|
-
const col =
|
|
1139
|
+
const col = safeColumns[colIndex];
|
|
1140
|
+
if (!col) return null;
|
|
1128
1141
|
const hasRender = !!col.render;
|
|
1129
1142
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1130
1143
|
"div",
|
|
@@ -1132,15 +1145,31 @@ var TableBody = ({
|
|
|
1132
1145
|
...colStyle.isPinned ? { "data-bt-pinned": "" } : {},
|
|
1133
1146
|
style: colStyle.style,
|
|
1134
1147
|
children: virtualItems.map((virtualRow) => {
|
|
1135
|
-
const row =
|
|
1148
|
+
const row = safeData[virtualRow.index];
|
|
1149
|
+
if (row == null) return null;
|
|
1136
1150
|
const rowKey = getRowKey ? getRowKey(row, virtualRow.index) : String(virtualRow.index);
|
|
1137
1151
|
const isSelected = selectedKeySet.has(rowKey);
|
|
1138
1152
|
const isExpanded = resolvedExpandedKeys?.has(rowKey) ?? false;
|
|
1139
1153
|
const cellValue = row[col.dataIndex];
|
|
1140
1154
|
const isRowShimmer = isLoading || rowKey.startsWith("__shimmer_");
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1155
|
+
let recordFingerprint;
|
|
1156
|
+
if (hasRender && !isRowShimmer) {
|
|
1157
|
+
try {
|
|
1158
|
+
recordFingerprint = JSON.stringify(row);
|
|
1159
|
+
} catch {
|
|
1160
|
+
recordFingerprint = rowKey;
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
let rowCls = "";
|
|
1164
|
+
try {
|
|
1165
|
+
rowCls = rowClassName ? rowClassName(row, virtualRow.index) : "";
|
|
1166
|
+
} catch {
|
|
1167
|
+
}
|
|
1168
|
+
let rowSty;
|
|
1169
|
+
try {
|
|
1170
|
+
rowSty = rowStyle ? rowStyle(row, virtualRow.index) : void 0;
|
|
1171
|
+
} catch {
|
|
1172
|
+
}
|
|
1144
1173
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1145
1174
|
"div",
|
|
1146
1175
|
{
|
|
@@ -1180,6 +1209,7 @@ var TableBody = ({
|
|
|
1180
1209
|
rowKey,
|
|
1181
1210
|
allData: allDataForSelection,
|
|
1182
1211
|
getRowKey,
|
|
1212
|
+
getRawRowKey,
|
|
1183
1213
|
accentColor,
|
|
1184
1214
|
isLoading: isRowShimmer,
|
|
1185
1215
|
recordFingerprint
|
|
@@ -1207,9 +1237,15 @@ var TableBody = ({
|
|
|
1207
1237
|
pointerEvents: "none"
|
|
1208
1238
|
},
|
|
1209
1239
|
children: virtualItems.map((virtualRow) => {
|
|
1210
|
-
const row =
|
|
1240
|
+
const row = safeData[virtualRow.index];
|
|
1241
|
+
if (row == null) return null;
|
|
1211
1242
|
const rk = getRowKey ? getRowKey(row, virtualRow.index) : String(virtualRow.index);
|
|
1212
1243
|
if (!(resolvedExpandedKeys?.has(rk) ?? false)) return null;
|
|
1244
|
+
let expandedRenderResult = null;
|
|
1245
|
+
try {
|
|
1246
|
+
expandedRenderResult = expandable.expandedRowRender(row, virtualRow.index, 0, true);
|
|
1247
|
+
} catch {
|
|
1248
|
+
}
|
|
1213
1249
|
const expandedContent = /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1214
1250
|
"div",
|
|
1215
1251
|
{
|
|
@@ -1227,7 +1263,7 @@ var TableBody = ({
|
|
|
1227
1263
|
...maxExpandedRowHeight ? { maxHeight: `${maxExpandedRowHeight}px` } : void 0,
|
|
1228
1264
|
...styles?.expandedRow
|
|
1229
1265
|
},
|
|
1230
|
-
children:
|
|
1266
|
+
children: expandedRenderResult
|
|
1231
1267
|
}
|
|
1232
1268
|
);
|
|
1233
1269
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
@@ -1274,11 +1310,20 @@ var TableBody = ({
|
|
|
1274
1310
|
boxShadow: "0 2px 6px -1px rgba(0,0,0,0.08)"
|
|
1275
1311
|
},
|
|
1276
1312
|
children: pinnedTopData.map((row, rowIdx) => {
|
|
1313
|
+
if (row == null) return null;
|
|
1277
1314
|
const rk = getRowKey ? getRowKey(row, rowIdx) : String(rowIdx);
|
|
1278
1315
|
const isSelected = selectedKeySet.has(rk);
|
|
1279
1316
|
const isExpanded = resolvedExpandedKeys?.has(rk) ?? false;
|
|
1280
|
-
|
|
1281
|
-
|
|
1317
|
+
let rowCls = "";
|
|
1318
|
+
try {
|
|
1319
|
+
rowCls = rowClassName ? rowClassName(row, rowIdx) : "";
|
|
1320
|
+
} catch {
|
|
1321
|
+
}
|
|
1322
|
+
let rowSty;
|
|
1323
|
+
try {
|
|
1324
|
+
rowSty = rowStyle ? rowStyle(row, rowIdx) : void 0;
|
|
1325
|
+
} catch {
|
|
1326
|
+
}
|
|
1282
1327
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1283
1328
|
"div",
|
|
1284
1329
|
{
|
|
@@ -1290,7 +1335,7 @@ var TableBody = ({
|
|
|
1290
1335
|
...styles?.pinnedRow,
|
|
1291
1336
|
...rowSty
|
|
1292
1337
|
},
|
|
1293
|
-
children:
|
|
1338
|
+
children: safeColumns.map((col) => {
|
|
1294
1339
|
const cellValue = row[col.dataIndex];
|
|
1295
1340
|
const stickyOffset = columnOffsets.get(col.key);
|
|
1296
1341
|
const isPinned = Boolean(col.pinned);
|
|
@@ -1298,7 +1343,14 @@ var TableBody = ({
|
|
|
1298
1343
|
if (col.key === "__select__" || col.key === "__expand__")
|
|
1299
1344
|
zIndex = 11;
|
|
1300
1345
|
else if (isPinned) zIndex = 2;
|
|
1301
|
-
|
|
1346
|
+
let recordFingerprint;
|
|
1347
|
+
if (col.render) {
|
|
1348
|
+
try {
|
|
1349
|
+
recordFingerprint = JSON.stringify(row);
|
|
1350
|
+
} catch {
|
|
1351
|
+
recordFingerprint = rk;
|
|
1352
|
+
}
|
|
1353
|
+
}
|
|
1302
1354
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1303
1355
|
"div",
|
|
1304
1356
|
{
|
|
@@ -1339,6 +1391,7 @@ var TableBody = ({
|
|
|
1339
1391
|
rowKey: rk,
|
|
1340
1392
|
allData: allDataForSelection,
|
|
1341
1393
|
getRowKey,
|
|
1394
|
+
getRawRowKey,
|
|
1342
1395
|
accentColor,
|
|
1343
1396
|
isLoading: false,
|
|
1344
1397
|
recordFingerprint
|
|
@@ -1382,11 +1435,20 @@ var TableBody = ({
|
|
|
1382
1435
|
boxShadow: "0 -2px 6px -1px rgba(0,0,0,0.08)"
|
|
1383
1436
|
},
|
|
1384
1437
|
children: pinnedBottomData.map((row, rowIdx) => {
|
|
1438
|
+
if (row == null) return null;
|
|
1385
1439
|
const rk = getRowKey ? getRowKey(row, rowIdx) : String(rowIdx);
|
|
1386
1440
|
const isSelected = selectedKeySet.has(rk);
|
|
1387
1441
|
const isExpanded = resolvedExpandedKeys?.has(rk) ?? false;
|
|
1388
|
-
|
|
1389
|
-
|
|
1442
|
+
let rowCls = "";
|
|
1443
|
+
try {
|
|
1444
|
+
rowCls = rowClassName ? rowClassName(row, rowIdx) : "";
|
|
1445
|
+
} catch {
|
|
1446
|
+
}
|
|
1447
|
+
let rowSty;
|
|
1448
|
+
try {
|
|
1449
|
+
rowSty = rowStyle ? rowStyle(row, rowIdx) : void 0;
|
|
1450
|
+
} catch {
|
|
1451
|
+
}
|
|
1390
1452
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1391
1453
|
"div",
|
|
1392
1454
|
{
|
|
@@ -1398,7 +1460,7 @@ var TableBody = ({
|
|
|
1398
1460
|
...styles?.pinnedRow,
|
|
1399
1461
|
...rowSty
|
|
1400
1462
|
},
|
|
1401
|
-
children:
|
|
1463
|
+
children: safeColumns.map((col) => {
|
|
1402
1464
|
const cellValue = row[col.dataIndex];
|
|
1403
1465
|
const stickyOffset = columnOffsets.get(col.key);
|
|
1404
1466
|
const isPinned = Boolean(col.pinned);
|
|
@@ -1406,7 +1468,14 @@ var TableBody = ({
|
|
|
1406
1468
|
if (col.key === "__select__" || col.key === "__expand__")
|
|
1407
1469
|
zIndex = 11;
|
|
1408
1470
|
else if (isPinned) zIndex = 2;
|
|
1409
|
-
|
|
1471
|
+
let recordFingerprint;
|
|
1472
|
+
if (col.render) {
|
|
1473
|
+
try {
|
|
1474
|
+
recordFingerprint = JSON.stringify(row);
|
|
1475
|
+
} catch {
|
|
1476
|
+
recordFingerprint = rk;
|
|
1477
|
+
}
|
|
1478
|
+
}
|
|
1410
1479
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1411
1480
|
"div",
|
|
1412
1481
|
{
|
|
@@ -1447,6 +1516,7 @@ var TableBody = ({
|
|
|
1447
1516
|
rowKey: rk,
|
|
1448
1517
|
allData: allDataForSelection,
|
|
1449
1518
|
getRowKey,
|
|
1519
|
+
getRawRowKey,
|
|
1450
1520
|
accentColor,
|
|
1451
1521
|
isLoading: false,
|
|
1452
1522
|
recordFingerprint
|
|
@@ -1482,9 +1552,11 @@ function arrayMove(arr, from, to) {
|
|
|
1482
1552
|
var SHIMMER_WIDTHS2 = [55, 70, 45, 80, 60, 50, 75, 65, 40, 72];
|
|
1483
1553
|
var EMPTY_CLASSNAMES = {};
|
|
1484
1554
|
var EMPTY_STYLES = {};
|
|
1555
|
+
var STABLE_EMPTY_DATA = [];
|
|
1556
|
+
var STABLE_EMPTY_COLS = [];
|
|
1485
1557
|
function BoltTable({
|
|
1486
|
-
columns:
|
|
1487
|
-
data,
|
|
1558
|
+
columns: rawInitialColumns,
|
|
1559
|
+
data: rawData,
|
|
1488
1560
|
rowHeight = 40,
|
|
1489
1561
|
expandedRowHeight = 200,
|
|
1490
1562
|
maxExpandedRowHeight,
|
|
@@ -1518,6 +1590,18 @@ function BoltTable({
|
|
|
1518
1590
|
rowClassName,
|
|
1519
1591
|
rowStyle
|
|
1520
1592
|
}) {
|
|
1593
|
+
const data = (0, import_react4.useMemo)(() => {
|
|
1594
|
+
if (!Array.isArray(rawData)) return STABLE_EMPTY_DATA;
|
|
1595
|
+
const filtered = rawData.filter((item) => item != null);
|
|
1596
|
+
return filtered.length > 0 ? filtered : STABLE_EMPTY_DATA;
|
|
1597
|
+
}, [rawData]);
|
|
1598
|
+
const initialColumns = (0, import_react4.useMemo)(() => {
|
|
1599
|
+
if (!Array.isArray(rawInitialColumns)) return STABLE_EMPTY_COLS;
|
|
1600
|
+
const filtered = rawInitialColumns.filter(
|
|
1601
|
+
(col) => col != null && typeof col.key === "string"
|
|
1602
|
+
);
|
|
1603
|
+
return filtered.length > 0 ? filtered : STABLE_EMPTY_COLS;
|
|
1604
|
+
}, [rawInitialColumns]);
|
|
1521
1605
|
const [columns, setColumns] = (0, import_react4.useState)(initialColumns);
|
|
1522
1606
|
const [columnOrder, setColumnOrder] = (0, import_react4.useState)(
|
|
1523
1607
|
() => initialColumns.map((c) => c.key)
|
|
@@ -1553,10 +1637,15 @@ function BoltTable({
|
|
|
1553
1637
|
[columns, columnWidths]
|
|
1554
1638
|
);
|
|
1555
1639
|
const [internalExpandedKeys, setInternalExpandedKeys] = (0, import_react4.useState)(() => {
|
|
1556
|
-
if (expandable?.defaultExpandAllRows) {
|
|
1640
|
+
if (expandable?.defaultExpandAllRows && data.length > 0) {
|
|
1557
1641
|
return new Set(
|
|
1558
1642
|
data.map((row, idx) => {
|
|
1559
|
-
if (
|
|
1643
|
+
if (row == null) return idx;
|
|
1644
|
+
try {
|
|
1645
|
+
if (typeof rowKey === "function") return rowKey(row);
|
|
1646
|
+
} catch {
|
|
1647
|
+
return idx;
|
|
1648
|
+
}
|
|
1560
1649
|
if (typeof rowKey === "string")
|
|
1561
1650
|
return row[rowKey] ?? idx;
|
|
1562
1651
|
return idx;
|
|
@@ -1590,21 +1679,56 @@ function BoltTable({
|
|
|
1590
1679
|
}, []);
|
|
1591
1680
|
const getRowKey = (0, import_react4.useCallback)(
|
|
1592
1681
|
(record, index) => {
|
|
1593
|
-
if (
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1682
|
+
if (record == null) return String(index);
|
|
1683
|
+
try {
|
|
1684
|
+
if (typeof rowKey === "function") return String(rowKey(record));
|
|
1685
|
+
if (typeof rowKey === "string") {
|
|
1686
|
+
const val = record[rowKey];
|
|
1687
|
+
return val != null ? String(val) : String(index);
|
|
1688
|
+
}
|
|
1689
|
+
} catch {
|
|
1690
|
+
return String(index);
|
|
1597
1691
|
}
|
|
1598
1692
|
return String(index);
|
|
1599
1693
|
},
|
|
1600
1694
|
[rowKey]
|
|
1601
1695
|
);
|
|
1696
|
+
const getRawRowKey = (0, import_react4.useCallback)(
|
|
1697
|
+
(record, index) => {
|
|
1698
|
+
if (record == null) return index;
|
|
1699
|
+
try {
|
|
1700
|
+
if (typeof rowKey === "function") return rowKey(record);
|
|
1701
|
+
if (typeof rowKey === "string") {
|
|
1702
|
+
const val = record[rowKey];
|
|
1703
|
+
if (typeof val === "number" || typeof val === "string") return val;
|
|
1704
|
+
return val != null ? String(val) : index;
|
|
1705
|
+
}
|
|
1706
|
+
} catch {
|
|
1707
|
+
return index;
|
|
1708
|
+
}
|
|
1709
|
+
return index;
|
|
1710
|
+
},
|
|
1711
|
+
[rowKey]
|
|
1712
|
+
);
|
|
1602
1713
|
const normalizedSelectedKeys = (0, import_react4.useMemo)(
|
|
1603
|
-
() =>
|
|
1714
|
+
() => {
|
|
1715
|
+
const keys = rowSelection?.selectedRowKeys;
|
|
1716
|
+
if (!Array.isArray(keys)) return [];
|
|
1717
|
+
return keys.filter((k) => k != null).map((k) => String(k));
|
|
1718
|
+
},
|
|
1604
1719
|
[rowSelection?.selectedRowKeys]
|
|
1605
1720
|
);
|
|
1721
|
+
const getRowKeyRef = (0, import_react4.useRef)(getRowKey);
|
|
1722
|
+
getRowKeyRef.current = getRowKey;
|
|
1723
|
+
const resolvedExpandedKeysRef = (0, import_react4.useRef)(resolvedExpandedKeys);
|
|
1724
|
+
resolvedExpandedKeysRef.current = resolvedExpandedKeys;
|
|
1725
|
+
const toggleExpandRef = (0, import_react4.useRef)(toggleExpand);
|
|
1726
|
+
toggleExpandRef.current = toggleExpand;
|
|
1727
|
+
const iconsRef = (0, import_react4.useRef)(icons);
|
|
1728
|
+
iconsRef.current = icons;
|
|
1729
|
+
const hasExpandable = !!expandable?.rowExpandable;
|
|
1606
1730
|
const columnsWithExpand = (0, import_react4.useMemo)(() => {
|
|
1607
|
-
if (!
|
|
1731
|
+
if (!hasExpandable) return columnsWithPersistedWidths;
|
|
1608
1732
|
const expandColumn = {
|
|
1609
1733
|
key: "__expand__",
|
|
1610
1734
|
dataIndex: "__expand__",
|
|
@@ -1613,17 +1737,17 @@ function BoltTable({
|
|
|
1613
1737
|
pinned: "left",
|
|
1614
1738
|
hidden: false,
|
|
1615
1739
|
render: (_, record, index) => {
|
|
1616
|
-
const key =
|
|
1617
|
-
const canExpand =
|
|
1618
|
-
const isExpanded =
|
|
1740
|
+
const key = getRowKeyRef.current(record, index);
|
|
1741
|
+
const canExpand = expandableRef.current?.rowExpandable?.(record) ?? true;
|
|
1742
|
+
const isExpanded = resolvedExpandedKeysRef.current.has(key);
|
|
1619
1743
|
if (!canExpand)
|
|
1620
1744
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { style: { display: "inline-block", width: 16 } });
|
|
1621
|
-
if (typeof
|
|
1622
|
-
return
|
|
1745
|
+
if (typeof expandableRef.current?.expandIcon === "function") {
|
|
1746
|
+
return expandableRef.current.expandIcon({
|
|
1623
1747
|
expanded: isExpanded,
|
|
1624
1748
|
onExpand: (_2, e) => {
|
|
1625
1749
|
e.stopPropagation();
|
|
1626
|
-
|
|
1750
|
+
toggleExpandRef.current(key);
|
|
1627
1751
|
},
|
|
1628
1752
|
record
|
|
1629
1753
|
});
|
|
@@ -1633,7 +1757,7 @@ function BoltTable({
|
|
|
1633
1757
|
{
|
|
1634
1758
|
onClick: (e) => {
|
|
1635
1759
|
e.stopPropagation();
|
|
1636
|
-
|
|
1760
|
+
toggleExpandRef.current(key);
|
|
1637
1761
|
},
|
|
1638
1762
|
style: {
|
|
1639
1763
|
display: "flex",
|
|
@@ -1646,20 +1770,13 @@ function BoltTable({
|
|
|
1646
1770
|
borderRadius: "3px",
|
|
1647
1771
|
color: accentColor
|
|
1648
1772
|
},
|
|
1649
|
-
children: isExpanded ?
|
|
1773
|
+
children: isExpanded ? iconsRef.current?.chevronDown ?? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ChevronDownIcon, { style: { width: 14, height: 14 } }) : iconsRef.current?.chevronRight ?? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ChevronRightIcon, { style: { width: 14, height: 14 } })
|
|
1650
1774
|
}
|
|
1651
1775
|
);
|
|
1652
1776
|
}
|
|
1653
1777
|
};
|
|
1654
1778
|
return [expandColumn, ...columnsWithPersistedWidths];
|
|
1655
|
-
}, [
|
|
1656
|
-
expandable,
|
|
1657
|
-
columnsWithPersistedWidths,
|
|
1658
|
-
getRowKey,
|
|
1659
|
-
resolvedExpandedKeys,
|
|
1660
|
-
toggleExpand,
|
|
1661
|
-
accentColor
|
|
1662
|
-
]);
|
|
1779
|
+
}, [hasExpandable, columnsWithPersistedWidths, accentColor]);
|
|
1663
1780
|
const columnsWithSelection = (0, import_react4.useMemo)(() => {
|
|
1664
1781
|
if (!rowSelection) return columnsWithExpand;
|
|
1665
1782
|
const selectionColumn = {
|
|
@@ -2019,36 +2136,52 @@ function BoltTable({
|
|
|
2019
2136
|
if (!onFilterChangeRef.current) {
|
|
2020
2137
|
const filterKeys = Object.keys(columnFilters);
|
|
2021
2138
|
if (filterKeys.length > 0) {
|
|
2022
|
-
result = result.filter(
|
|
2023
|
-
(row
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2139
|
+
result = result.filter((row) => {
|
|
2140
|
+
if (row == null) return false;
|
|
2141
|
+
return filterKeys.every((key) => {
|
|
2142
|
+
try {
|
|
2143
|
+
const col = columnsLookupRef.current.find((c) => c.key === key);
|
|
2144
|
+
if (typeof col?.filterFn === "function") {
|
|
2145
|
+
return col.filterFn(columnFilters[key], row, col.dataIndex);
|
|
2146
|
+
}
|
|
2147
|
+
const cellVal = String(row[key] ?? "").toLowerCase();
|
|
2148
|
+
return cellVal.includes(columnFilters[key].toLowerCase());
|
|
2149
|
+
} catch {
|
|
2150
|
+
return true;
|
|
2027
2151
|
}
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
})
|
|
2031
|
-
);
|
|
2152
|
+
});
|
|
2153
|
+
});
|
|
2032
2154
|
}
|
|
2033
2155
|
}
|
|
2034
2156
|
if (!onSortChangeRef.current && sortState.key && sortState.direction) {
|
|
2035
2157
|
const dir = sortState.direction === "asc" ? 1 : -1;
|
|
2036
2158
|
const key = sortState.key;
|
|
2037
2159
|
const col = columnsLookupRef.current.find((c) => c.key === key);
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2160
|
+
try {
|
|
2161
|
+
if (typeof col?.sorter === "function") {
|
|
2162
|
+
const sorterFn = col.sorter;
|
|
2163
|
+
result = [...result].sort((a, b) => {
|
|
2164
|
+
if (a == null && b == null) return 0;
|
|
2165
|
+
if (a == null) return 1;
|
|
2166
|
+
if (b == null) return -1;
|
|
2167
|
+
return sorterFn(a, b) * dir;
|
|
2168
|
+
});
|
|
2169
|
+
} else {
|
|
2170
|
+
result = [...result].sort((a, b) => {
|
|
2171
|
+
if (a == null && b == null) return 0;
|
|
2172
|
+
if (a == null) return 1;
|
|
2173
|
+
if (b == null) return -1;
|
|
2174
|
+
const aVal = a[key];
|
|
2175
|
+
const bVal = b[key];
|
|
2176
|
+
if (aVal == null && bVal == null) return 0;
|
|
2177
|
+
if (aVal == null) return 1;
|
|
2178
|
+
if (bVal == null) return -1;
|
|
2179
|
+
if (typeof aVal === "number" && typeof bVal === "number")
|
|
2180
|
+
return (aVal - bVal) * dir;
|
|
2181
|
+
return String(aVal).localeCompare(String(bVal)) * dir;
|
|
2182
|
+
});
|
|
2183
|
+
}
|
|
2184
|
+
} catch {
|
|
2052
2185
|
}
|
|
2053
2186
|
}
|
|
2054
2187
|
return result;
|
|
@@ -2067,6 +2200,7 @@ function BoltTable({
|
|
|
2067
2200
|
const bottomMap = /* @__PURE__ */ new Map();
|
|
2068
2201
|
const rest = [];
|
|
2069
2202
|
processedData.forEach((row, idx) => {
|
|
2203
|
+
if (row == null) return;
|
|
2070
2204
|
const key = getRowKey(row, idx);
|
|
2071
2205
|
if (topKeySet.has(key)) topMap.set(key, row);
|
|
2072
2206
|
else if (bottomKeySet.has(key)) bottomMap.set(key, row);
|
|
@@ -2128,7 +2262,8 @@ function BoltTable({
|
|
|
2128
2262
|
const DEFAULT_PAGE_SIZE = 15;
|
|
2129
2263
|
const [internalPage, setInternalPage] = (0, import_react4.useState)(1);
|
|
2130
2264
|
const [internalPageSize, setInternalPageSize] = (0, import_react4.useState)(DEFAULT_PAGE_SIZE);
|
|
2131
|
-
const
|
|
2265
|
+
const dataLength = data.length;
|
|
2266
|
+
const autoPagination = pagination === void 0 && dataLength > DEFAULT_PAGE_SIZE;
|
|
2132
2267
|
const pgEnabled = pagination === false ? false : !!pagination || autoPagination;
|
|
2133
2268
|
const pgSize = pgEnabled && typeof pagination === "object" && pagination?.pageSize !== void 0 ? pagination.pageSize : internalPageSize;
|
|
2134
2269
|
const isControlledPagination = typeof pagination === "object" && pagination?.current !== void 0;
|
|
@@ -2141,26 +2276,27 @@ function BoltTable({
|
|
|
2141
2276
|
}, [unpinnedProcessedData, needsClientPagination, pgCurrent, pgSize]);
|
|
2142
2277
|
const shimmerCount = pgEnabled ? pgSize : 15;
|
|
2143
2278
|
const showShimmer = isLoading && processedData.length === 0;
|
|
2279
|
+
const shimmerRowKeyField = typeof rowKey === "string" ? rowKey : "id";
|
|
2144
2280
|
const shimmerData = (0, import_react4.useMemo)(() => {
|
|
2145
2281
|
if (!showShimmer) return null;
|
|
2146
2282
|
return Array.from(
|
|
2147
2283
|
{ length: shimmerCount },
|
|
2148
2284
|
(_, i) => ({
|
|
2149
|
-
[
|
|
2285
|
+
[shimmerRowKeyField]: `__shimmer_${i}__`
|
|
2150
2286
|
})
|
|
2151
2287
|
);
|
|
2152
|
-
}, [showShimmer, shimmerCount,
|
|
2288
|
+
}, [showShimmer, shimmerCount, shimmerRowKeyField]);
|
|
2153
2289
|
const INFINITE_SHIMMER_COUNT = 5;
|
|
2290
|
+
const showInfiniteShimmer = isLoading && paginatedData.length > 0 && !showShimmer && !pgEnabled;
|
|
2154
2291
|
const infiniteLoadingShimmer = (0, import_react4.useMemo)(() => {
|
|
2155
|
-
if (!
|
|
2156
|
-
if (pgEnabled) return null;
|
|
2292
|
+
if (!showInfiniteShimmer) return null;
|
|
2157
2293
|
return Array.from(
|
|
2158
2294
|
{ length: INFINITE_SHIMMER_COUNT },
|
|
2159
2295
|
(_, i) => ({
|
|
2160
|
-
[
|
|
2296
|
+
[shimmerRowKeyField]: `__shimmer_${i}__`
|
|
2161
2297
|
})
|
|
2162
2298
|
);
|
|
2163
|
-
}, [
|
|
2299
|
+
}, [showInfiniteShimmer, shimmerRowKeyField]);
|
|
2164
2300
|
const displayData = (0, import_react4.useMemo)(() => {
|
|
2165
2301
|
if (shimmerData) return shimmerData;
|
|
2166
2302
|
if (infiniteLoadingShimmer)
|
|
@@ -2190,13 +2326,20 @@ function BoltTable({
|
|
|
2190
2326
|
getScrollElement: () => tableAreaRef.current,
|
|
2191
2327
|
estimateSize: (index) => {
|
|
2192
2328
|
if (shimmerData) return rowHeight;
|
|
2193
|
-
const
|
|
2329
|
+
const item = displayData[index];
|
|
2330
|
+
if (!item) return rowHeight;
|
|
2331
|
+
const key = getRowKey(item, index);
|
|
2194
2332
|
if (!resolvedExpandedKeys.has(key)) return rowHeight;
|
|
2195
2333
|
const cached = measuredExpandedHeights.current.get(key);
|
|
2196
2334
|
return cached ? rowHeight + cached : rowHeight + expandedRowHeight;
|
|
2197
2335
|
},
|
|
2198
2336
|
overscan: 5,
|
|
2199
|
-
getItemKey: (index) =>
|
|
2337
|
+
getItemKey: (index) => {
|
|
2338
|
+
if (shimmerData) return `__shimmer_${index}__`;
|
|
2339
|
+
const item = displayData[index];
|
|
2340
|
+
if (!item) return `__fallback_${index}__`;
|
|
2341
|
+
return getRowKey(item, index);
|
|
2342
|
+
},
|
|
2200
2343
|
paddingStart: pinnedTopHeight,
|
|
2201
2344
|
paddingEnd: pinnedBottomHeight
|
|
2202
2345
|
});
|
|
@@ -2216,7 +2359,7 @@ function BoltTable({
|
|
|
2216
2359
|
endReachedFiredRef.current = false;
|
|
2217
2360
|
}, 200);
|
|
2218
2361
|
return () => clearTimeout(timer);
|
|
2219
|
-
}, [
|
|
2362
|
+
}, [dataLength, isLoading]);
|
|
2220
2363
|
import_react4.default.useEffect(() => {
|
|
2221
2364
|
const el = tableAreaRef.current;
|
|
2222
2365
|
if (!el) return;
|
|
@@ -2238,7 +2381,7 @@ function BoltTable({
|
|
|
2238
2381
|
const activeColumn = activeId ? orderedColumns.find((col) => col.key === activeId) : null;
|
|
2239
2382
|
const currentPage = pgCurrent;
|
|
2240
2383
|
const pageSize = pgSize;
|
|
2241
|
-
const rawTotal = pgEnabled ? (typeof pagination === "object" ? pagination?.total : void 0) ?? (needsClientPagination ? unpinnedProcessedData.length :
|
|
2384
|
+
const rawTotal = pgEnabled ? (typeof pagination === "object" ? pagination?.total : void 0) ?? (needsClientPagination ? unpinnedProcessedData.length : dataLength) : dataLength;
|
|
2242
2385
|
const lastKnownTotalRef = (0, import_react4.useRef)(0);
|
|
2243
2386
|
if (!isLoading || rawTotal > 0) {
|
|
2244
2387
|
lastKnownTotalRef.current = rawTotal;
|
|
@@ -2246,8 +2389,8 @@ function BoltTable({
|
|
|
2246
2389
|
const total = isLoading && lastKnownTotalRef.current > 0 ? lastKnownTotalRef.current : rawTotal;
|
|
2247
2390
|
const totalPages = Math.max(1, Math.ceil(total / pageSize));
|
|
2248
2391
|
import_react4.default.useEffect(() => {
|
|
2249
|
-
if (internalPage > totalPages) {
|
|
2250
|
-
setInternalPage(
|
|
2392
|
+
if (totalPages > 0 && internalPage > totalPages) {
|
|
2393
|
+
setInternalPage(totalPages);
|
|
2251
2394
|
}
|
|
2252
2395
|
}, [totalPages, internalPage]);
|
|
2253
2396
|
const handlePageChange = (p) => {
|
|
@@ -2582,16 +2725,16 @@ function BoltTable({
|
|
|
2582
2725
|
"input",
|
|
2583
2726
|
{
|
|
2584
2727
|
type: "checkbox",
|
|
2585
|
-
checked:
|
|
2728
|
+
checked: dataLength > 0 && normalizedSelectedKeys.length === dataLength,
|
|
2586
2729
|
ref: (input) => {
|
|
2587
2730
|
if (input) {
|
|
2588
|
-
input.indeterminate = normalizedSelectedKeys.length > 0 && normalizedSelectedKeys.length <
|
|
2731
|
+
input.indeterminate = normalizedSelectedKeys.length > 0 && normalizedSelectedKeys.length < dataLength;
|
|
2589
2732
|
}
|
|
2590
2733
|
},
|
|
2591
2734
|
onChange: (e) => {
|
|
2592
2735
|
if (e.target.checked) {
|
|
2593
2736
|
const allKeys = data.map(
|
|
2594
|
-
(row, idx) =>
|
|
2737
|
+
(row, idx) => getRawRowKey(row, idx)
|
|
2595
2738
|
);
|
|
2596
2739
|
rowSelection.onSelectAll?.(
|
|
2597
2740
|
true,
|
|
@@ -2720,6 +2863,7 @@ function BoltTable({
|
|
|
2720
2863
|
rowSelection: !showShimmer ? rowSelection : void 0,
|
|
2721
2864
|
normalizedSelectedKeys,
|
|
2722
2865
|
getRowKey,
|
|
2866
|
+
getRawRowKey,
|
|
2723
2867
|
expandable: !showShimmer ? expandable : void 0,
|
|
2724
2868
|
resolvedExpandedKeys,
|
|
2725
2869
|
rowHeight,
|
|
@@ -3058,6 +3202,7 @@ function BoltTable({
|
|
|
3058
3202
|
...pinnedBottomRows
|
|
3059
3203
|
];
|
|
3060
3204
|
for (let i = 0; i < allRows.length; i++) {
|
|
3205
|
+
if (allRows[i] == null) continue;
|
|
3061
3206
|
const rk = getRowKey(allRows[i], i);
|
|
3062
3207
|
if (rk === cellContextMenu.rowKey) {
|
|
3063
3208
|
menuRecord = allRows[i];
|