@lensui/lens-table 0.1.4 → 0.1.6
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 +46 -61
- package/dist/index.cjs +764 -170
- package/dist/index.css +362 -31
- package/dist/index.d.cts +39 -33
- package/dist/index.d.ts +39 -33
- package/dist/index.js +764 -170
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -57,6 +57,7 @@ var ZH_CN_GRID_LABELS = {
|
|
|
57
57
|
sortDesc: "\u5F53\u524D\uFF1A\u964D\u5E8F",
|
|
58
58
|
sortBoth: "\u5347\u5E8F / \u964D\u5E8F",
|
|
59
59
|
dragColumn: "\u62D6\u52A8\u5217\u6392\u5E8F",
|
|
60
|
+
revealSelectedCell: "\u5B9A\u4F4D\u5230\u9009\u4E2D\u5355\u5143\u683C",
|
|
60
61
|
previousYear: "\u4E0A\u4E00\u5E74",
|
|
61
62
|
nextYear: "\u4E0B\u4E00\u5E74",
|
|
62
63
|
previousMonth: "\u4E0A\u4E2A\u6708",
|
|
@@ -125,6 +126,7 @@ var EN_US_GRID_LABELS = {
|
|
|
125
126
|
sortDesc: "Current: descending",
|
|
126
127
|
sortBoth: "Ascending / descending",
|
|
127
128
|
dragColumn: "Drag column to reorder",
|
|
129
|
+
revealSelectedCell: "Reveal selected cell",
|
|
128
130
|
previousYear: "Previous year",
|
|
129
131
|
nextYear: "Next year",
|
|
130
132
|
previousMonth: "Previous month",
|
|
@@ -316,16 +318,6 @@ function ContextMenuIcon({ type }) {
|
|
|
316
318
|
};
|
|
317
319
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { className: "rvg-context-menu-svg", viewBox: "0 0 16 16", "aria-hidden": "true", children: paths[type].map((path) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: path }, path)) });
|
|
318
320
|
}
|
|
319
|
-
function RowDragHandleIcon() {
|
|
320
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { viewBox: "0 0 16 16", focusable: "false", children: [
|
|
321
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "5", cy: "4", r: "1" }),
|
|
322
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "11", cy: "4", r: "1" }),
|
|
323
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "5", cy: "8", r: "1" }),
|
|
324
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "11", cy: "8", r: "1" }),
|
|
325
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "5", cy: "12", r: "1" }),
|
|
326
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "11", cy: "12", r: "1" })
|
|
327
|
-
] });
|
|
328
|
-
}
|
|
329
321
|
function LoadingSpinnerIcon() {
|
|
330
322
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M20 12a8 8 0 1 1-3.1-6.3" }) });
|
|
331
323
|
}
|
|
@@ -333,7 +325,6 @@ function LoadingSpinnerIcon() {
|
|
|
333
325
|
// src/components/editors/ChoiceEditor.tsx
|
|
334
326
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
335
327
|
function ChoiceEditor({ value, options, style, labels, onChange, onCommit, onCancel }) {
|
|
336
|
-
const editorStyle = typeof style.width === "number" ? { ...style, width: Math.max(0, style.width - 1) } : style;
|
|
337
328
|
const collection = (0, import_select.createListCollection)({
|
|
338
329
|
items: options,
|
|
339
330
|
itemToValue: (item) => item.value,
|
|
@@ -343,7 +334,7 @@ function ChoiceEditor({ value, options, style, labels, onChange, onCommit, onCan
|
|
|
343
334
|
import_select.Select.Root,
|
|
344
335
|
{
|
|
345
336
|
className: "rvg-choice-editor",
|
|
346
|
-
style
|
|
337
|
+
style,
|
|
347
338
|
collection,
|
|
348
339
|
value: value ? [value] : [],
|
|
349
340
|
defaultOpen: true,
|
|
@@ -754,6 +745,48 @@ function createRowDragHandleSvg() {
|
|
|
754
745
|
}
|
|
755
746
|
return svg;
|
|
756
747
|
}
|
|
748
|
+
function createHeaderDragHandleSvg() {
|
|
749
|
+
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
750
|
+
svg.setAttribute("viewBox", "0 0 14 14");
|
|
751
|
+
svg.setAttribute("aria-hidden", "true");
|
|
752
|
+
for (const cy of [2.5, 7, 11.5]) {
|
|
753
|
+
const circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
|
|
754
|
+
circle.setAttribute("cx", "7");
|
|
755
|
+
circle.setAttribute("cy", String(cy));
|
|
756
|
+
circle.setAttribute("r", "1.25");
|
|
757
|
+
svg.appendChild(circle);
|
|
758
|
+
}
|
|
759
|
+
return svg;
|
|
760
|
+
}
|
|
761
|
+
function createHeaderSortSvg(direction) {
|
|
762
|
+
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
763
|
+
svg.setAttribute("viewBox", "0 0 14 14");
|
|
764
|
+
svg.setAttribute("aria-hidden", "true");
|
|
765
|
+
for (const [value, active] of [
|
|
766
|
+
["M3 5.5 7 1.5l4 4Z", direction === "asc"],
|
|
767
|
+
["M3 8.5 7 12.5l4-4Z", direction === "desc"]
|
|
768
|
+
]) {
|
|
769
|
+
const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
|
770
|
+
path.setAttribute("d", value);
|
|
771
|
+
if (active) path.classList.add("is-active");
|
|
772
|
+
svg.appendChild(path);
|
|
773
|
+
}
|
|
774
|
+
return svg;
|
|
775
|
+
}
|
|
776
|
+
function createHeaderSearchSvg(active) {
|
|
777
|
+
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
778
|
+
svg.setAttribute("viewBox", "0 0 14 14");
|
|
779
|
+
svg.setAttribute("aria-hidden", "true");
|
|
780
|
+
if (active) svg.classList.add("is-active");
|
|
781
|
+
const circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
|
|
782
|
+
circle.setAttribute("cx", "5.5");
|
|
783
|
+
circle.setAttribute("cy", "5.5");
|
|
784
|
+
circle.setAttribute("r", "4.25");
|
|
785
|
+
const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
|
786
|
+
path.setAttribute("d", "m8.75 8.75 2.25 2.25");
|
|
787
|
+
svg.append(circle, path);
|
|
788
|
+
return svg;
|
|
789
|
+
}
|
|
757
790
|
|
|
758
791
|
// src/Table.tsx
|
|
759
792
|
var import_adapter = require("@atlaskit/pragmatic-drag-and-drop/element/adapter");
|
|
@@ -774,6 +807,7 @@ function getDisplayLabel(column, row, rowIndex) {
|
|
|
774
807
|
|
|
775
808
|
// src/core/layout.ts
|
|
776
809
|
var DEFAULT_COLUMN_WIDTH = 140;
|
|
810
|
+
var HEADER_ACTION_SLOT_WIDTH = 16;
|
|
777
811
|
function isDataColumn(column) {
|
|
778
812
|
return !column.rowSelection && !column.rowDragHandle && !column.rowNumber;
|
|
779
813
|
}
|
|
@@ -788,7 +822,7 @@ function getHeaderTitleRequiredWidth(column, titleWidth) {
|
|
|
788
822
|
return minimumReadableTitleWidth + (column.align === "center" ? 20 : 22);
|
|
789
823
|
}
|
|
790
824
|
function getVisibleHeaderActions(column, width, columnDraggable = false, titleWidth = 26) {
|
|
791
|
-
const capacity = Math.max(0, Math.floor((width - getHeaderTitleRequiredWidth(column, titleWidth)) /
|
|
825
|
+
const capacity = Math.max(0, Math.floor((width - getHeaderTitleRequiredWidth(column, titleWidth)) / HEADER_ACTION_SLOT_WIDTH));
|
|
792
826
|
const candidates = [
|
|
793
827
|
isColumnFilterable(column) ? "filter" : null,
|
|
794
828
|
isColumnSortable(column) ? "sort" : null,
|
|
@@ -867,12 +901,15 @@ var COLORS = {
|
|
|
867
901
|
grid: "#e3e6e8",
|
|
868
902
|
text: "#202124",
|
|
869
903
|
muted: "#5f6368",
|
|
904
|
+
icon: "#9aa0a6",
|
|
905
|
+
borderStrong: "#b8bec4",
|
|
870
906
|
selection: "#1677ff",
|
|
871
907
|
selectionFill: "#edf4ff",
|
|
872
908
|
axisSelectionFill: "#e8f2ff",
|
|
873
909
|
rowHoverFill: "#f6f9fc",
|
|
874
910
|
editedFill: "#fff1b8",
|
|
875
911
|
insertedFill: "#c8ead4",
|
|
912
|
+
columnDropTargetFill: "#eeeeee",
|
|
876
913
|
stripe: "#fafbfc"
|
|
877
914
|
};
|
|
878
915
|
function ellipsizeText(context, text, maxWidth) {
|
|
@@ -892,7 +929,7 @@ function ellipsizeText(context, text, maxWidth) {
|
|
|
892
929
|
return `${text.slice(0, start)}${ellipsis}`;
|
|
893
930
|
}
|
|
894
931
|
function paintGrid(options) {
|
|
895
|
-
const { context: ctx, width, height, pixelRatio, scrollLeft, scrollTop, rowHeight, headerHeight, fixedHeader, verticalBorderless, striped, columnDraggable, sortState, filterValues, hoveredHeaderAction, rows, columns, metrics, range, selection, editing, hoveredRowIndex, selectionRange, selectedRowKeys, selectedColumnKeys, highlightEditedCells, highlightInsertedRows, insertedRowKeys, editedCellKeys, cellAnnotations, getRowKey, rowDragPreview } = options;
|
|
932
|
+
const { context: ctx, width, height, pixelRatio, scrollLeft, scrollTop, rowHeight, headerHeight, fixedHeader, verticalBorderless, striped, columnDraggable, sortState, filterValues, hoveredHeaderAction, rows, columns, metrics, range, selection, editing, hoveredRowIndex, selectionRange, selectedRowKeys, rowSelectionMode, selectedColumnKeys, highlightEditedCells, highlightInsertedRows, insertedRowKeys, editedCellKeys, cellAnnotations, getRowKey, rowDragPreview, columnDropTarget } = options;
|
|
896
933
|
const headerLeafTop = options.headerLeafTop ?? 0;
|
|
897
934
|
const headerLeafHeight = options.headerLeafHeight ?? headerHeight;
|
|
898
935
|
const colors = { ...COLORS, ...options.colors };
|
|
@@ -914,6 +951,7 @@ function paintGrid(options) {
|
|
|
914
951
|
const leftFixedWidth = columns.reduce((value, column, index) => column.fixed === "left" ? value + metrics[index].width : value, 0);
|
|
915
952
|
const rightFixedWidth = columns.reduce((value, column, index) => column.fixed === "right" ? value + metrics[index].width : value, 0);
|
|
916
953
|
const rightFixedLeft = width - rightFixedWidth;
|
|
954
|
+
const rightFixedBoundaryInset = rightFixedWidth > 0 && !verticalBorderless ? 1 : 0;
|
|
917
955
|
const leftOffsets = /* @__PURE__ */ new Map();
|
|
918
956
|
let leftOffset = 0;
|
|
919
957
|
for (let index = 0; index < columns.length; index += 1) {
|
|
@@ -937,11 +975,19 @@ function paintGrid(options) {
|
|
|
937
975
|
const getColumnX = (index) => {
|
|
938
976
|
return columns[index].fixed === "left" ? leftOffsets.get(index) ?? 0 : columns[index].fixed === "right" ? width - (rightOffsets.get(index) ?? 0) - metrics[index].width : (scrollableLefts.get(index) ?? leftFixedWidth) - scrollLeft;
|
|
939
977
|
};
|
|
978
|
+
const getRowDragOffset = (rowIndex) => {
|
|
979
|
+
if (!rowDragPreview || rowIndex === rowDragPreview.sourceIndex) return 0;
|
|
980
|
+
if (rowDragPreview.sourceIndex < rowDragPreview.targetIndex) {
|
|
981
|
+
return rowIndex > rowDragPreview.sourceIndex && rowIndex <= rowDragPreview.targetIndex ? -rowHeight : 0;
|
|
982
|
+
}
|
|
983
|
+
return rowIndex >= rowDragPreview.targetIndex && rowIndex < rowDragPreview.sourceIndex ? rowHeight : 0;
|
|
984
|
+
};
|
|
985
|
+
const rowBelowDragGap = rowDragPreview ? rowDragPreview.sourceIndex <= rowDragPreview.targetIndex ? rowDragPreview.targetIndex + 1 : rowDragPreview.targetIndex : -1;
|
|
940
986
|
const paintBodyColumns = (layer) => {
|
|
941
987
|
const rowStart = Math.max(0, range.rowStart - Math.max(0, options.maxRowSpan - 1));
|
|
942
988
|
for (let rowIndex = rowStart; rowIndex < range.rowEnd; rowIndex += 1) {
|
|
943
989
|
if (rowDragPreview?.sourceIndex === rowIndex) continue;
|
|
944
|
-
const shift =
|
|
990
|
+
const shift = getRowDragOffset(rowIndex);
|
|
945
991
|
const y = bodyTop + rowIndex * rowHeight - scrollTop + shift;
|
|
946
992
|
const row = rows[rowIndex];
|
|
947
993
|
const rowKey = getRowKey(row, rowIndex);
|
|
@@ -974,6 +1020,10 @@ function paintGrid(options) {
|
|
|
974
1020
|
ctx.fillStyle = colors.rowHoverFill;
|
|
975
1021
|
ctx.fillRect(x, y, cellWidth, cellHeight);
|
|
976
1022
|
}
|
|
1023
|
+
if (columnDropTarget && columnIndex >= columnDropTarget.startIndex && columnIndex <= columnDropTarget.endIndex) {
|
|
1024
|
+
ctx.fillStyle = colors.columnDropTargetFill;
|
|
1025
|
+
ctx.fillRect(x, y, cellWidth, cellHeight);
|
|
1026
|
+
}
|
|
977
1027
|
if (highlightInsertedRows && insertedRowKeys.has(rowKey)) {
|
|
978
1028
|
ctx.fillStyle = colors.insertedFill;
|
|
979
1029
|
ctx.fillRect(x, y, cellWidth, cellHeight);
|
|
@@ -1000,6 +1050,7 @@ function paintGrid(options) {
|
|
|
1000
1050
|
}
|
|
1001
1051
|
ctx.fillStyle = colors.grid;
|
|
1002
1052
|
if (!verticalBorderless) ctx.fillRect(x + cellWidth - 1, y, 1, cellHeight);
|
|
1053
|
+
if (rowIndex === rowBelowDragGap) ctx.fillRect(x, y, cellWidth, 1);
|
|
1003
1054
|
if (!options.suppressLastRowBottomBorder || rowIndex !== rows.length - 1) {
|
|
1004
1055
|
ctx.fillRect(x, y + cellHeight - 1, cellWidth, 1);
|
|
1005
1056
|
}
|
|
@@ -1026,6 +1077,59 @@ function paintGrid(options) {
|
|
|
1026
1077
|
if (columnIndex === rangeColumnStart) ctx.fillRect(x, y, 2, cellHeight);
|
|
1027
1078
|
if (columnIndex === rangeColumnEnd) ctx.fillRect(x + cellWidth - 2, y, 2, cellHeight);
|
|
1028
1079
|
}
|
|
1080
|
+
if (column.rowDragHandle) {
|
|
1081
|
+
const iconLeft = x + (cellWidth - 16) / 2;
|
|
1082
|
+
const iconTop = y + (cellHeight - 16) / 2;
|
|
1083
|
+
ctx.fillStyle = colors.icon;
|
|
1084
|
+
ctx.beginPath();
|
|
1085
|
+
for (const circleX of [5, 11]) {
|
|
1086
|
+
for (const circleY of [4, 8, 12]) {
|
|
1087
|
+
ctx.moveTo(iconLeft + circleX + 1, iconTop + circleY);
|
|
1088
|
+
ctx.arc(iconLeft + circleX, iconTop + circleY, 1, 0, Math.PI * 2);
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1091
|
+
ctx.fill();
|
|
1092
|
+
}
|
|
1093
|
+
if (column.rowSelection) {
|
|
1094
|
+
const iconLeft = x + (cellWidth - 16) / 2;
|
|
1095
|
+
const iconTop = y + (cellHeight - 16) / 2;
|
|
1096
|
+
const checked = selectedRowKeys.has(rowKey);
|
|
1097
|
+
ctx.save();
|
|
1098
|
+
ctx.lineWidth = 1;
|
|
1099
|
+
if (rowSelectionMode === "single") {
|
|
1100
|
+
ctx.beginPath();
|
|
1101
|
+
ctx.arc(iconLeft + 8, iconTop + 8, 6.25, 0, Math.PI * 2);
|
|
1102
|
+
ctx.fillStyle = colors.background;
|
|
1103
|
+
ctx.fill();
|
|
1104
|
+
ctx.strokeStyle = checked ? colors.selection : colors.borderStrong;
|
|
1105
|
+
ctx.stroke();
|
|
1106
|
+
if (checked) {
|
|
1107
|
+
ctx.beginPath();
|
|
1108
|
+
ctx.arc(iconLeft + 8, iconTop + 8, 3.25, 0, Math.PI * 2);
|
|
1109
|
+
ctx.fillStyle = colors.selection;
|
|
1110
|
+
ctx.fill();
|
|
1111
|
+
}
|
|
1112
|
+
} else {
|
|
1113
|
+
ctx.beginPath();
|
|
1114
|
+
ctx.roundRect(iconLeft + 1.5, iconTop + 1.5, 13, 13, 3);
|
|
1115
|
+
ctx.fillStyle = checked ? colors.selection : colors.background;
|
|
1116
|
+
ctx.fill();
|
|
1117
|
+
ctx.strokeStyle = checked ? colors.selection : colors.borderStrong;
|
|
1118
|
+
ctx.stroke();
|
|
1119
|
+
if (checked) {
|
|
1120
|
+
ctx.beginPath();
|
|
1121
|
+
ctx.moveTo(iconLeft + 4.1, iconTop + 8);
|
|
1122
|
+
ctx.lineTo(iconLeft + 6.45, iconTop + 10.35);
|
|
1123
|
+
ctx.lineTo(iconLeft + 11.9, iconTop + 5.15);
|
|
1124
|
+
ctx.strokeStyle = colors.background;
|
|
1125
|
+
ctx.lineWidth = 1.75;
|
|
1126
|
+
ctx.lineCap = "round";
|
|
1127
|
+
ctx.lineJoin = "round";
|
|
1128
|
+
ctx.stroke();
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
ctx.restore();
|
|
1132
|
+
}
|
|
1029
1133
|
if (!column.rowDragHandle && !column.rowSelection && !column.renderCell && !(editing?.rowIndex === rowIndex && editing.columnIndex === columnIndex)) {
|
|
1030
1134
|
let label = "";
|
|
1031
1135
|
try {
|
|
@@ -1081,6 +1185,10 @@ function paintGrid(options) {
|
|
|
1081
1185
|
ctx.fillStyle = colors.selectionFill;
|
|
1082
1186
|
ctx.fillRect(x, headerY, metric.width, headerHeight);
|
|
1083
1187
|
}
|
|
1188
|
+
if (columnDropTarget && columnIndex >= columnDropTarget.startIndex && columnIndex <= columnDropTarget.endIndex) {
|
|
1189
|
+
ctx.fillStyle = colors.columnDropTargetFill;
|
|
1190
|
+
ctx.fillRect(x, headerY, metric.width, headerHeight);
|
|
1191
|
+
}
|
|
1084
1192
|
ctx.fillStyle = colors.grid;
|
|
1085
1193
|
if (!verticalBorderless) ctx.fillRect(x + metric.width - 1, headerY, 1, headerHeight);
|
|
1086
1194
|
ctx.fillRect(x, headerY + headerHeight - 1, metric.width, 1);
|
|
@@ -1089,7 +1197,7 @@ function paintGrid(options) {
|
|
|
1089
1197
|
ctx.font = "600 13px Inter, ui-sans-serif, system-ui, sans-serif";
|
|
1090
1198
|
const titleWidth = ctx.measureText(column.title).width;
|
|
1091
1199
|
const visibleActions = getVisibleHeaderActions(column, metric.width, columnDraggable, titleWidth);
|
|
1092
|
-
const actionWidth = (Number(visibleActions.drag) + Number(visibleActions.filter) + Number(visibleActions.sort)) *
|
|
1200
|
+
const actionWidth = (Number(visibleActions.drag) + Number(visibleActions.filter) + Number(visibleActions.sort)) * HEADER_ACTION_SLOT_WIDTH;
|
|
1093
1201
|
const contentWidth = Math.max(0, metric.width - actionWidth);
|
|
1094
1202
|
const padding = 10;
|
|
1095
1203
|
const clipWidth = contentWidth;
|
|
@@ -1137,28 +1245,28 @@ function paintGrid(options) {
|
|
|
1137
1245
|
const markerBottom = Math.min(bottom, height);
|
|
1138
1246
|
const startX = getColumnX(columnStart);
|
|
1139
1247
|
const endX = getColumnX(columnEnd) + metrics[columnEnd].width;
|
|
1140
|
-
const visibleLeft = columns[columnStart].fixed === "left" ? Math.max(0, startX) : Math.max(leftFixedWidth
|
|
1248
|
+
const visibleLeft = columns[columnStart].fixed === "left" ? Math.max(0, startX) : Math.max(leftFixedWidth, startX);
|
|
1141
1249
|
const visibleRight = columns[columnEnd].fixed === "right" ? Math.min(width, endX) : Math.min(rightFixedLeft, endX);
|
|
1142
1250
|
ctx.fillStyle = colors.selection;
|
|
1143
1251
|
if (markerBottom > markerTop) {
|
|
1144
1252
|
if (columns[columnStart].fixed === void 0 && startX < leftFixedWidth) {
|
|
1145
|
-
ctx.fillRect(Math.max(0, leftFixedWidth
|
|
1253
|
+
ctx.fillRect(Math.max(0, leftFixedWidth), markerTop, 2, markerBottom - markerTop);
|
|
1146
1254
|
}
|
|
1147
1255
|
if (columns[columnEnd].fixed === void 0 && endX > rightFixedLeft) {
|
|
1148
|
-
ctx.fillRect(Math.max(0, rightFixedLeft -
|
|
1256
|
+
ctx.fillRect(Math.max(0, rightFixedLeft - 2 - rightFixedBoundaryInset), markerTop, 2, markerBottom - markerTop);
|
|
1149
1257
|
}
|
|
1150
1258
|
}
|
|
1151
1259
|
if (visibleRight > visibleLeft) {
|
|
1152
1260
|
if (top < clipTop) ctx.fillRect(visibleLeft, clipTop, visibleRight - visibleLeft, 2);
|
|
1153
1261
|
if (bottom > height) ctx.fillRect(visibleLeft, height - 2, visibleRight - visibleLeft, 2);
|
|
1154
1262
|
} else if (top < clipTop || bottom > height) {
|
|
1155
|
-
const markerX = endX <= leftFixedWidth ? Math.max(0, leftFixedWidth
|
|
1263
|
+
const markerX = endX <= leftFixedWidth ? Math.max(0, leftFixedWidth) : Math.max(0, rightFixedLeft - 2 - rightFixedBoundaryInset);
|
|
1156
1264
|
ctx.fillRect(markerX, top < clipTop ? clipTop : height - 2, 2, 2);
|
|
1157
1265
|
}
|
|
1158
1266
|
}
|
|
1159
1267
|
const selectedRow = selection ? rows[selection.rowIndex] : void 0;
|
|
1160
1268
|
const hasValidSelection = Boolean(selection && selectedRow && getRowKey(selectedRow, selection.rowIndex) === selection.rowKey);
|
|
1161
|
-
if (selection && hasValidSelection && !selectionRange) {
|
|
1269
|
+
if (selection && hasValidSelection && !selectionRange && !rowDragPreview) {
|
|
1162
1270
|
const metric = metrics[selection.columnIndex];
|
|
1163
1271
|
if (metric) {
|
|
1164
1272
|
const fixedSide = columns[selection.columnIndex].fixed;
|
|
@@ -1167,22 +1275,22 @@ function paintGrid(options) {
|
|
|
1167
1275
|
const selectionWidth = getCellWidth(selection.columnIndex, span?.colSpan ?? 1);
|
|
1168
1276
|
const selectionHeight = rowHeight * (span?.rowSpan ?? 1);
|
|
1169
1277
|
const x = Math.round(getColumnX(selection.columnIndex));
|
|
1170
|
-
const y = Math.round(bodyTop + selection.rowIndex * rowHeight - scrollTop);
|
|
1278
|
+
const y = Math.round(bodyTop + selection.rowIndex * rowHeight - scrollTop + getRowDragOffset(selection.rowIndex));
|
|
1171
1279
|
const borderWidth = 2;
|
|
1172
1280
|
const visibleLeft = fixedSide === "left" ? 0 : leftFixedWidth;
|
|
1173
1281
|
const selectionAreaRight = fixedSide === "right" ? width : width - rightFixedWidth;
|
|
1174
1282
|
const visibleRight = x + selectionWidth;
|
|
1175
1283
|
const visibleBottom = y + selectionHeight;
|
|
1176
1284
|
const selectionTop = fixedHeader ? bodyTop : 0;
|
|
1177
|
-
const selectionClipTop =
|
|
1285
|
+
const selectionClipTop = selectionTop;
|
|
1178
1286
|
const hiddenAboveHeader = visibleBottom <= selectionTop;
|
|
1179
1287
|
const hiddenBelowViewport = y >= height;
|
|
1180
1288
|
const hiddenBehindLeft = !isFixed && visibleRight <= visibleLeft;
|
|
1181
1289
|
const hiddenBehindRight = !isFixed && x >= selectionAreaRight;
|
|
1182
|
-
const leftMarkerX = Math.max(0, leftFixedWidth
|
|
1290
|
+
const leftMarkerX = Math.max(0, leftFixedWidth);
|
|
1183
1291
|
if ((hiddenAboveHeader || hiddenBelowViewport) && (hiddenBehindLeft || hiddenBehindRight)) {
|
|
1184
1292
|
const markerSize = 2;
|
|
1185
|
-
const markerX = hiddenBehindLeft ? leftMarkerX : selectionAreaRight - borderWidth;
|
|
1293
|
+
const markerX = hiddenBehindLeft ? leftMarkerX : selectionAreaRight - borderWidth - rightFixedBoundaryInset;
|
|
1186
1294
|
const markerY = hiddenAboveHeader ? selectionClipTop : height - markerSize;
|
|
1187
1295
|
ctx.fillStyle = colors.selection;
|
|
1188
1296
|
ctx.fillRect(markerX, markerY, markerSize, markerSize);
|
|
@@ -1190,7 +1298,7 @@ function paintGrid(options) {
|
|
|
1190
1298
|
}
|
|
1191
1299
|
ctx.save();
|
|
1192
1300
|
ctx.beginPath();
|
|
1193
|
-
const clipLeft = fixedSide === "left" ? 0 : Math.max(0, leftFixedWidth
|
|
1301
|
+
const clipLeft = fixedSide === "left" ? 0 : Math.max(0, leftFixedWidth);
|
|
1194
1302
|
const clipRight = Math.min(width, selectionAreaRight + 1);
|
|
1195
1303
|
ctx.rect(clipLeft, selectionClipTop, clipRight - clipLeft, height - selectionClipTop);
|
|
1196
1304
|
ctx.clip();
|
|
@@ -1208,14 +1316,14 @@ function paintGrid(options) {
|
|
|
1208
1316
|
if (hiddenBehindLeft || hiddenBehindRight) {
|
|
1209
1317
|
const markerTop = Math.max(y - borderWidth, selectionTop);
|
|
1210
1318
|
const markerBottom = Math.min(y + selectionHeight + 1, height);
|
|
1211
|
-
const markerX = hiddenBehindLeft ? leftMarkerX : selectionAreaRight - borderWidth;
|
|
1319
|
+
const markerX = hiddenBehindLeft ? leftMarkerX : selectionAreaRight - borderWidth - rightFixedBoundaryInset;
|
|
1212
1320
|
ctx.fillRect(markerX, markerTop, borderWidth, Math.max(0, markerBottom - markerTop));
|
|
1213
1321
|
}
|
|
1214
1322
|
if (hiddenAboveHeader || hiddenBelowViewport || hiddenBehindLeft || hiddenBehindRight) {
|
|
1215
1323
|
ctx.restore();
|
|
1216
1324
|
return;
|
|
1217
1325
|
}
|
|
1218
|
-
const borderLeft = x <= 0 ? 0 : Math.max(x - borderWidth, visibleLeft
|
|
1326
|
+
const borderLeft = x <= 0 ? 0 : Math.max(x - borderWidth, visibleLeft);
|
|
1219
1327
|
const borderRight = Math.min(x + selectionWidth - 1, selectionAreaRight - borderWidth, width - borderWidth);
|
|
1220
1328
|
const borderTop = Math.max(y - borderWidth, selectionClipTop);
|
|
1221
1329
|
const borderBottom = Math.min(y + selectionHeight - 1, height - borderWidth);
|
|
@@ -1277,6 +1385,40 @@ function flattenDataColumns(columns, inheritedFixed, insideGroup = false) {
|
|
|
1277
1385
|
return flattenDataColumns(column.children, column.fixed ?? inheritedFixed, true);
|
|
1278
1386
|
});
|
|
1279
1387
|
}
|
|
1388
|
+
function reconcileColumns(current, incoming) {
|
|
1389
|
+
const incomingByKey = new Map(incoming.map((column) => [column.key, column]));
|
|
1390
|
+
const ordered = current.flatMap((column) => {
|
|
1391
|
+
const replacement = incomingByKey.get(column.key);
|
|
1392
|
+
if (!replacement) return [];
|
|
1393
|
+
incomingByKey.delete(column.key);
|
|
1394
|
+
return [{
|
|
1395
|
+
...replacement,
|
|
1396
|
+
children: replacement.children ? reconcileColumns(column.children ?? [], replacement.children) : void 0
|
|
1397
|
+
}];
|
|
1398
|
+
});
|
|
1399
|
+
incoming.forEach((column) => {
|
|
1400
|
+
if (incomingByKey.has(column.key)) ordered.push(column);
|
|
1401
|
+
});
|
|
1402
|
+
return ordered;
|
|
1403
|
+
}
|
|
1404
|
+
function reorderColumns(columns, detail) {
|
|
1405
|
+
const reorder = (items) => {
|
|
1406
|
+
const sourceIndex = items.findIndex((column2) => column2.key === detail.sourceKey);
|
|
1407
|
+
const targetIndex = items.findIndex((column2) => column2.key === detail.targetKey);
|
|
1408
|
+
if (sourceIndex < 0 || targetIndex < 0 || sourceIndex === targetIndex) return items;
|
|
1409
|
+
const next = items.slice();
|
|
1410
|
+
const [column] = next.splice(sourceIndex, 1);
|
|
1411
|
+
let insertIndex = targetIndex + (detail.placement === "after" ? 1 : 0);
|
|
1412
|
+
if (sourceIndex < insertIndex) insertIndex -= 1;
|
|
1413
|
+
next.splice(insertIndex, 0, column);
|
|
1414
|
+
return next;
|
|
1415
|
+
};
|
|
1416
|
+
if (!detail.parentKey) return reorder(columns);
|
|
1417
|
+
return columns.map((column) => {
|
|
1418
|
+
if (column.key === detail.parentKey && column.children) return { ...column, children: reorder(column.children) };
|
|
1419
|
+
return column.children ? { ...column, children: reorderColumns(column.children, detail) } : column;
|
|
1420
|
+
});
|
|
1421
|
+
}
|
|
1280
1422
|
function buildHeaderCells(sourceColumns, utilityColumnCount, depth) {
|
|
1281
1423
|
const cells = [];
|
|
1282
1424
|
let leafIndex = utilityColumnCount;
|
|
@@ -1324,6 +1466,25 @@ var createEmptyCellSpanLookup = () => ({
|
|
|
1324
1466
|
covered: /* @__PURE__ */ new Map(),
|
|
1325
1467
|
maxRowSpan: 1
|
|
1326
1468
|
});
|
|
1469
|
+
var summaryFunctionIds = /* @__PURE__ */ new WeakMap();
|
|
1470
|
+
var nextSummaryFunctionId = 1;
|
|
1471
|
+
function getSummaryFunctionId(fn) {
|
|
1472
|
+
if (!fn) return "";
|
|
1473
|
+
const existing = summaryFunctionIds.get(fn);
|
|
1474
|
+
if (existing !== void 0) return existing;
|
|
1475
|
+
const next = nextSummaryFunctionId;
|
|
1476
|
+
nextSummaryFunctionId += 1;
|
|
1477
|
+
summaryFunctionIds.set(fn, next);
|
|
1478
|
+
return next;
|
|
1479
|
+
}
|
|
1480
|
+
function getSummarySignature(columns) {
|
|
1481
|
+
return columns.filter((column) => Boolean(column.summary)).map((column) => [
|
|
1482
|
+
column.key,
|
|
1483
|
+
String(column.dataIndex ?? ""),
|
|
1484
|
+
typeof column.summary === "function" ? getSummaryFunctionId(column.summary) : "sum",
|
|
1485
|
+
getSummaryFunctionId(column.formatter)
|
|
1486
|
+
].join("")).join("");
|
|
1487
|
+
}
|
|
1327
1488
|
async function calculateSummaryValues(columns, rows) {
|
|
1328
1489
|
const values = /* @__PURE__ */ new Map();
|
|
1329
1490
|
for (const column of columns) {
|
|
@@ -1362,7 +1523,7 @@ function resolveContextMenuSection(section, defaults) {
|
|
|
1362
1523
|
return defaults;
|
|
1363
1524
|
}
|
|
1364
1525
|
function Table({
|
|
1365
|
-
columns:
|
|
1526
|
+
columns: columnProps,
|
|
1366
1527
|
rows: sourceRows,
|
|
1367
1528
|
rowKey,
|
|
1368
1529
|
width = "100%",
|
|
@@ -1391,23 +1552,21 @@ function Table({
|
|
|
1391
1552
|
rowSelection,
|
|
1392
1553
|
selectedRowKeys,
|
|
1393
1554
|
defaultSelectedRowKeys,
|
|
1394
|
-
|
|
1555
|
+
onSelectedRowChange,
|
|
1395
1556
|
columnSelection,
|
|
1396
1557
|
selectedColumnKeys,
|
|
1397
1558
|
defaultSelectedColumnKeys,
|
|
1398
|
-
|
|
1559
|
+
onSelectedColumnChange,
|
|
1399
1560
|
columnDraggable = true,
|
|
1400
|
-
columnResizable =
|
|
1401
|
-
|
|
1561
|
+
columnResizable = true,
|
|
1562
|
+
onColumnsReorder,
|
|
1402
1563
|
onColumnResize,
|
|
1403
1564
|
rowDraggable = false,
|
|
1404
|
-
|
|
1565
|
+
onRowsReorder,
|
|
1405
1566
|
onInsertRows,
|
|
1406
1567
|
onDeleteRows,
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
filterValues = {},
|
|
1410
|
-
onFilterValuesChange,
|
|
1568
|
+
onSortChange,
|
|
1569
|
+
onFilterChange,
|
|
1411
1570
|
onCellChange,
|
|
1412
1571
|
onCellContextMenu,
|
|
1413
1572
|
contextMenu: contextMenuConfig = true,
|
|
@@ -1416,6 +1575,10 @@ function Table({
|
|
|
1416
1575
|
style,
|
|
1417
1576
|
ariaLabel = "Data grid"
|
|
1418
1577
|
}) {
|
|
1578
|
+
const [sourceColumns, setSourceColumns] = (0, import_react5.useState)(columnProps);
|
|
1579
|
+
(0, import_react5.useEffect)(() => {
|
|
1580
|
+
setSourceColumns((current) => reconcileColumns(current, columnProps));
|
|
1581
|
+
}, [columnProps]);
|
|
1419
1582
|
const rowHeight = layout?.rowHeight ?? rowHeightProp ?? 36;
|
|
1420
1583
|
const baseHeaderHeight = layout?.headerHeight ?? headerHeightProp ?? 40;
|
|
1421
1584
|
const headerDepth = (0, import_react5.useMemo)(() => Math.max(1, ...sourceColumns.map(getColumnDepth)), [sourceColumns]);
|
|
@@ -1496,7 +1659,6 @@ function Table({
|
|
|
1496
1659
|
const frameRef = (0, import_react5.useRef)(null);
|
|
1497
1660
|
const textFrameRef = (0, import_react5.useRef)(null);
|
|
1498
1661
|
const toastTimerRef = (0, import_react5.useRef)(null);
|
|
1499
|
-
const sortDebounceRef = (0, import_react5.useRef)(null);
|
|
1500
1662
|
const headerTooltipTimerRef = (0, import_react5.useRef)(null);
|
|
1501
1663
|
const cellTooltipTimerRef = (0, import_react5.useRef)(null);
|
|
1502
1664
|
const pendingHeaderTooltipKeyRef = (0, import_react5.useRef)("");
|
|
@@ -1508,6 +1670,7 @@ function Table({
|
|
|
1508
1670
|
const dragGuideRef = (0, import_react5.useRef)(null);
|
|
1509
1671
|
const rowDragGuideRef = (0, import_react5.useRef)(null);
|
|
1510
1672
|
const selectionFocusRef = (0, import_react5.useRef)(null);
|
|
1673
|
+
const selectionEdgeTargetRef = (0, import_react5.useRef)(null);
|
|
1511
1674
|
const verticalScrollbarRef = (0, import_react5.useRef)(null);
|
|
1512
1675
|
const verticalScrollbarThumbRef = (0, import_react5.useRef)(null);
|
|
1513
1676
|
const verticalScrollbarDragRef = (0, import_react5.useRef)(null);
|
|
@@ -1526,6 +1689,7 @@ function Table({
|
|
|
1526
1689
|
const suppressClickRef = (0, import_react5.useRef)(false);
|
|
1527
1690
|
const hasCompletedLoadRef = (0, import_react5.useRef)(!loading);
|
|
1528
1691
|
const columnDragPreviewRef = (0, import_react5.useRef)(null);
|
|
1692
|
+
const validColumnDropRef = (0, import_react5.useRef)(null);
|
|
1529
1693
|
const hoveredHeaderActionRef = (0, import_react5.useRef)(null);
|
|
1530
1694
|
const hoveredRowIndexRef = (0, import_react5.useRef)(null);
|
|
1531
1695
|
const [viewport, setViewport] = (0, import_react5.useState)({ width: 0, height: typeof height === "number" ? height : FALLBACK_HEIGHT });
|
|
@@ -1533,11 +1697,8 @@ function Table({
|
|
|
1533
1697
|
const resolvedHeight = typeof height === "number" ? height : viewport.height || FALLBACK_HEIGHT;
|
|
1534
1698
|
const [scrollPosition, setScrollPosition] = (0, import_react5.useState)({ left: 0, top: 0 });
|
|
1535
1699
|
const scrollRef = (0, import_react5.useRef)({ left: 0, top: 0 });
|
|
1536
|
-
const [selection, setSelection] = useControllableValue(selectedCell, defaultSelectedCell, onSelectedCellChange);
|
|
1537
|
-
const [selectionRange, setSelectionRange] = (0, import_react5.useState)(null);
|
|
1538
|
-
const rangeDragRef = (0, import_react5.useRef)(null);
|
|
1539
1700
|
const [rowKeys, setRowKeys] = useControllableKeys(selectedRowKeys, defaultSelectedRowKeys, (keys) => {
|
|
1540
|
-
if (!
|
|
1701
|
+
if (!onSelectedRowChange) return;
|
|
1541
1702
|
const missing = new Set(keys.filter((key) => !rowByKeyRef.current.has(key)));
|
|
1542
1703
|
if (missing.size > 0) {
|
|
1543
1704
|
for (let index = 0; index < rows.length && missing.size > 0; index += 1) {
|
|
@@ -1554,12 +1715,13 @@ function Table({
|
|
|
1554
1715
|
const index = rowIndexByKeyRef.current.get(key);
|
|
1555
1716
|
return row && index !== void 0 ? [{ row, index }] : [];
|
|
1556
1717
|
});
|
|
1557
|
-
|
|
1718
|
+
onSelectedRowChange(keys, entries.map(({ row }) => row), entries.map(({ index }) => index));
|
|
1558
1719
|
});
|
|
1559
|
-
const [columnKeys, setColumnKeys] = useControllableKeys(selectedColumnKeys, defaultSelectedColumnKeys,
|
|
1720
|
+
const [columnKeys, setColumnKeys] = useControllableKeys(selectedColumnKeys, defaultSelectedColumnKeys, onSelectedColumnChange);
|
|
1560
1721
|
const [editing, setEditing] = (0, import_react5.useState)(null);
|
|
1561
1722
|
const [draft, setDraft] = (0, import_react5.useState)("");
|
|
1562
1723
|
const [rowDragPreview, setRowDragPreview] = (0, import_react5.useState)(null);
|
|
1724
|
+
const [columnDropTarget, setColumnDropTarget] = (0, import_react5.useState)(null);
|
|
1563
1725
|
(0, import_react5.useEffect)(() => {
|
|
1564
1726
|
if (!loading) hasCompletedLoadRef.current = true;
|
|
1565
1727
|
}, [loading]);
|
|
@@ -1628,6 +1790,8 @@ function Table({
|
|
|
1628
1790
|
return () => observer.disconnect();
|
|
1629
1791
|
}, [activeCustomHeaderLevels, measureCustomHeaderHeight, viewport.width]);
|
|
1630
1792
|
const [filterEditor, setFilterEditor] = (0, import_react5.useState)(null);
|
|
1793
|
+
const [filterValues, setFilterValues] = (0, import_react5.useState)({});
|
|
1794
|
+
const [sortState, setSortState] = (0, import_react5.useState)(null);
|
|
1631
1795
|
const [contextMenu, setContextMenu] = (0, import_react5.useState)(null);
|
|
1632
1796
|
const [insertCounts, setInsertCounts] = (0, import_react5.useState)({ before: 1, after: 1 });
|
|
1633
1797
|
const [confirmAction, setConfirmAction] = (0, import_react5.useState)(null);
|
|
@@ -1640,7 +1804,20 @@ function Table({
|
|
|
1640
1804
|
const [hoveredHeaderAction, setHoveredHeaderAction] = (0, import_react5.useState)(null);
|
|
1641
1805
|
const [visibleHeaderTooltip, setVisibleHeaderTooltip] = (0, import_react5.useState)(null);
|
|
1642
1806
|
const [hoveredCellTooltip, setHoveredCellTooltip] = (0, import_react5.useState)(null);
|
|
1643
|
-
const
|
|
1807
|
+
const hideDragTooltips = (0, import_react5.useCallback)(() => {
|
|
1808
|
+
if (headerTooltipTimerRef.current !== null) {
|
|
1809
|
+
clearTimeout(headerTooltipTimerRef.current);
|
|
1810
|
+
headerTooltipTimerRef.current = null;
|
|
1811
|
+
}
|
|
1812
|
+
if (cellTooltipTimerRef.current !== null) {
|
|
1813
|
+
clearTimeout(cellTooltipTimerRef.current);
|
|
1814
|
+
cellTooltipTimerRef.current = null;
|
|
1815
|
+
}
|
|
1816
|
+
pendingHeaderTooltipKeyRef.current = "";
|
|
1817
|
+
pendingCellTooltipKeyRef.current = "";
|
|
1818
|
+
setVisibleHeaderTooltip(null);
|
|
1819
|
+
setHoveredCellTooltip(null);
|
|
1820
|
+
}, []);
|
|
1644
1821
|
const [editedCellKeys, setEditedCellKeys] = (0, import_react5.useState)(() => /* @__PURE__ */ new Set());
|
|
1645
1822
|
const [cellAnnotations, setCellAnnotations] = (0, import_react5.useState)(() => /* @__PURE__ */ new Map());
|
|
1646
1823
|
const [annotationType, setAnnotationType] = (0, import_react5.useState)("corner");
|
|
@@ -1652,6 +1829,7 @@ function Table({
|
|
|
1652
1829
|
const [pendingDeletedRowKeys, setPendingDeletedRowKeys] = (0, import_react5.useState)(() => /* @__PURE__ */ new Set());
|
|
1653
1830
|
const [pendingInserts, setPendingInserts] = (0, import_react5.useState)(() => []);
|
|
1654
1831
|
const [insertedRowKeys, setInsertedRowKeys] = (0, import_react5.useState)(() => /* @__PURE__ */ new Set());
|
|
1832
|
+
const [rowOrderKeys, setRowOrderKeys] = (0, import_react5.useState)(null);
|
|
1655
1833
|
const settledPendingInsertIdsRef = (0, import_react5.useRef)(/* @__PURE__ */ new Set());
|
|
1656
1834
|
const getDataRowKey = (0, import_react5.useCallback)((row, index) => {
|
|
1657
1835
|
return typeof rowKey === "function" ? rowKey(row, index) : rowKey ? row[rowKey] : getDefaultRowKey(row, index);
|
|
@@ -1666,7 +1844,7 @@ function Table({
|
|
|
1666
1844
|
}
|
|
1667
1845
|
return sourceRows.findIndex((sourceRow, index) => getDataRowKey(sourceRow, index) === key);
|
|
1668
1846
|
}, [getDataRowKey, sourceRows]);
|
|
1669
|
-
const
|
|
1847
|
+
const orderedRows = (0, import_react5.useMemo)(() => {
|
|
1670
1848
|
let next = sourceRows;
|
|
1671
1849
|
if (pendingInserts.length > 0) {
|
|
1672
1850
|
const activeInserts = pendingInserts.filter((insert) => {
|
|
@@ -1685,9 +1863,91 @@ function Table({
|
|
|
1685
1863
|
insertedOffset += insert.rows.length;
|
|
1686
1864
|
});
|
|
1687
1865
|
}
|
|
1688
|
-
if (pendingDeletedRowKeys.size
|
|
1689
|
-
|
|
1690
|
-
|
|
1866
|
+
if (pendingDeletedRowKeys.size > 0) {
|
|
1867
|
+
next = next.filter((row, index) => !pendingDeletedRowKeys.has(getDataRowKey(row, index)));
|
|
1868
|
+
}
|
|
1869
|
+
if (!rowOrderKeys) return next;
|
|
1870
|
+
const rowsByKey = new Map(next.map((row, index) => [getDataRowKey(row, index), row]));
|
|
1871
|
+
const ordered = rowOrderKeys.flatMap((key) => {
|
|
1872
|
+
const row = rowsByKey.get(key);
|
|
1873
|
+
if (!row) return [];
|
|
1874
|
+
rowsByKey.delete(key);
|
|
1875
|
+
return [row];
|
|
1876
|
+
});
|
|
1877
|
+
next.forEach((row, index) => {
|
|
1878
|
+
const key = getDataRowKey(row, index);
|
|
1879
|
+
if (rowsByKey.has(key)) ordered.push(row);
|
|
1880
|
+
});
|
|
1881
|
+
return ordered;
|
|
1882
|
+
}, [getDataRowKey, pendingDeletedRowKeys, pendingInserts, rowOrderKeys, sourceRows]);
|
|
1883
|
+
const activeFilterValues = (0, import_react5.useMemo)(() => Object.fromEntries(
|
|
1884
|
+
Object.entries(filterValues).filter(([, value]) => value.trim() !== "")
|
|
1885
|
+
), [filterValues]);
|
|
1886
|
+
const filteredRows = (0, import_react5.useMemo)(() => {
|
|
1887
|
+
if (Object.keys(activeFilterValues).length === 0) return orderedRows;
|
|
1888
|
+
if (onFilterChange) return onFilterChange(orderedRows, activeFilterValues);
|
|
1889
|
+
return orderedRows.filter((row, rowIndex) => Object.entries(activeFilterValues).every(([columnKey, query]) => {
|
|
1890
|
+
const column = columns.find((candidate) => candidate.key === columnKey);
|
|
1891
|
+
if (!column) return true;
|
|
1892
|
+
return getDisplayLabel(column, row, rowIndex).toLocaleLowerCase().includes(query.trim().toLocaleLowerCase());
|
|
1893
|
+
}));
|
|
1894
|
+
}, [activeFilterValues, columns, onFilterChange, orderedRows]);
|
|
1895
|
+
const rows = (0, import_react5.useMemo)(() => {
|
|
1896
|
+
if (!sortState) return filteredRows;
|
|
1897
|
+
if (onSortChange) return onSortChange(filteredRows, sortState);
|
|
1898
|
+
const column = columns.find((candidate) => candidate.key === sortState.columnKey);
|
|
1899
|
+
if (!column) return filteredRows;
|
|
1900
|
+
const direction = sortState.direction === "asc" ? 1 : -1;
|
|
1901
|
+
return filteredRows.slice().sort((left, right) => {
|
|
1902
|
+
const leftValue = column.dataIndex === void 0 ? void 0 : left[column.dataIndex];
|
|
1903
|
+
const rightValue = column.dataIndex === void 0 ? void 0 : right[column.dataIndex];
|
|
1904
|
+
const result = typeof leftValue === "number" && typeof rightValue === "number" ? leftValue - rightValue : getDisplayLabel(column, left, 0).localeCompare(getDisplayLabel(column, right, 0), language);
|
|
1905
|
+
return result * direction;
|
|
1906
|
+
});
|
|
1907
|
+
}, [columns, filteredRows, language, onSortChange, sortState]);
|
|
1908
|
+
const resolveSelectionTarget = (0, import_react5.useCallback)((target) => {
|
|
1909
|
+
if (target == null) return target;
|
|
1910
|
+
const columnIndex = columns.findIndex((column) => column.key === target.columnKey);
|
|
1911
|
+
const rowIndex = target.rowKey !== void 0 ? rows.findIndex((row2, index) => getDataRowKey(row2, index) === target.rowKey) : target.rowIndex ?? -1;
|
|
1912
|
+
const row = rows[rowIndex];
|
|
1913
|
+
if (columnIndex < 0 || !row) return null;
|
|
1914
|
+
return {
|
|
1915
|
+
rowIndex,
|
|
1916
|
+
columnIndex,
|
|
1917
|
+
rowKey: getDataRowKey(row, rowIndex),
|
|
1918
|
+
columnKey: target.columnKey
|
|
1919
|
+
};
|
|
1920
|
+
}, [columns, getDataRowKey, rows]);
|
|
1921
|
+
const resolvedSelectedCell = (0, import_react5.useMemo)(() => resolveSelectionTarget(selectedCell), [resolveSelectionTarget, selectedCell]);
|
|
1922
|
+
const resolvedDefaultSelectedCell = (0, import_react5.useMemo)(() => resolveSelectionTarget(defaultSelectedCell), [defaultSelectedCell, resolveSelectionTarget]);
|
|
1923
|
+
const handleSelectedCellChange = (0, import_react5.useCallback)((next) => {
|
|
1924
|
+
if (!onSelectedCellChange) return;
|
|
1925
|
+
if (!next) {
|
|
1926
|
+
onSelectedCellChange(null);
|
|
1927
|
+
return;
|
|
1928
|
+
}
|
|
1929
|
+
const row = rows[next.rowIndex];
|
|
1930
|
+
const column = columns[next.columnIndex];
|
|
1931
|
+
const value = row && column?.dataIndex !== void 0 ? row[column.dataIndex] : void 0;
|
|
1932
|
+
onSelectedCellChange({ ...next, value });
|
|
1933
|
+
}, [columns, onSelectedCellChange, rows]);
|
|
1934
|
+
const [selection, setSelection] = useControllableValue(resolvedSelectedCell, resolvedDefaultSelectedCell, handleSelectedCellChange);
|
|
1935
|
+
const [selectionRange, setSelectionRange] = (0, import_react5.useState)(null);
|
|
1936
|
+
const rangeDragRef = (0, import_react5.useRef)(null);
|
|
1937
|
+
const applyRowOrder = (0, import_react5.useCallback)((sourceIndex, targetIndex) => {
|
|
1938
|
+
if (sourceIndex === targetIndex || sourceIndex < 0 || targetIndex < 0 || sourceIndex >= rows.length || targetIndex >= rows.length) return;
|
|
1939
|
+
const nextEntries = rows.map((row, index) => ({ row, key: getDataRowKey(row, index) }));
|
|
1940
|
+
const [entry] = nextEntries.splice(sourceIndex, 1);
|
|
1941
|
+
nextEntries.splice(targetIndex, 0, entry);
|
|
1942
|
+
const nextRows = nextEntries.map(({ row }) => row);
|
|
1943
|
+
setRowOrderKeys(nextEntries.map(({ key }) => key));
|
|
1944
|
+
onRowsReorder?.(nextRows, { sourceIndex, targetIndex });
|
|
1945
|
+
}, [getDataRowKey, onRowsReorder, rows]);
|
|
1946
|
+
const applyColumnOrder = (0, import_react5.useCallback)((sourceIndex, targetIndex, detail) => {
|
|
1947
|
+
const nextColumns = reorderColumns(sourceColumns, detail);
|
|
1948
|
+
setSourceColumns(nextColumns);
|
|
1949
|
+
onColumnsReorder?.(nextColumns, { sourceIndex, targetIndex, ...detail });
|
|
1950
|
+
}, [onColumnsReorder, sourceColumns]);
|
|
1691
1951
|
(0, import_react5.useEffect)(() => {
|
|
1692
1952
|
if (insertBusy || settledPendingInsertIdsRef.current.size === 0) return;
|
|
1693
1953
|
setPendingInserts((current) => {
|
|
@@ -1755,7 +2015,8 @@ function Table({
|
|
|
1755
2015
|
const getScrollableColumnLeft = (0, import_react5.useCallback)((columnIndex) => scrollableColumnLefts[columnIndex] ?? fixedWidth, [fixedWidth, scrollableColumnLefts]);
|
|
1756
2016
|
const hasRowSelectionColumn = (0, import_react5.useMemo)(() => columns.some((column) => column.rowSelection), [columns]);
|
|
1757
2017
|
const rowSelectionMode = typeof rowSelection === "object" ? rowSelection.mode ?? "multiple" : "multiple";
|
|
1758
|
-
const
|
|
2018
|
+
const summarySignature = (0, import_react5.useMemo)(() => getSummarySignature(columns), [columns]);
|
|
2019
|
+
const hasSummaryRow = rows.length > 0 && summaryEnabled && summarySignature.length > 0;
|
|
1759
2020
|
const topSummaryHeight = hasSummaryRow && summaryPosition === "top" ? rowHeight : 0;
|
|
1760
2021
|
const bottomSummaryHeight = hasSummaryRow && summaryPosition === "bottom" ? rowHeight : 0;
|
|
1761
2022
|
const bodyTop = headerHeight + topSummaryHeight;
|
|
@@ -1764,21 +2025,21 @@ function Table({
|
|
|
1764
2025
|
const effectiveHeight = autoHeight ? Math.max(bodyTop + bottomSummaryHeight, Math.min(resolvedHeight, realContentHeight)) : resolvedHeight;
|
|
1765
2026
|
const renderHeight = Math.max(0, effectiveHeight - bottomSummaryHeight);
|
|
1766
2027
|
const bodyViewportHeight = Math.max(0, renderHeight - (fixedHeader ? headerHeight + topSummaryHeight : 0));
|
|
1767
|
-
const [summaryState, setSummaryState] = (0, import_react5.useState)(() => ({
|
|
1768
|
-
const summaryPending = hasSummaryRow && (loading || summaryState.pending || summaryState.
|
|
1769
|
-
const summaryValues = hasSummaryRow && summaryState.
|
|
2028
|
+
const [summaryState, setSummaryState] = (0, import_react5.useState)(() => ({ signature: "", rows: null, values: /* @__PURE__ */ new Map(), pending: false }));
|
|
2029
|
+
const summaryPending = hasSummaryRow && (loading || summaryState.pending || summaryState.signature !== summarySignature || summaryState.rows !== rows);
|
|
2030
|
+
const summaryValues = hasSummaryRow && summaryState.signature === summarySignature && summaryState.rows === rows ? summaryState.values : /* @__PURE__ */ new Map();
|
|
1770
2031
|
(0, import_react5.useEffect)(() => {
|
|
1771
2032
|
let cancelled = false;
|
|
1772
2033
|
if (!hasSummaryRow) {
|
|
1773
|
-
setSummaryState((current) => current.
|
|
2034
|
+
setSummaryState((current) => current.signature === "" && current.rows === null && current.values.size === 0 && !current.pending ? current : { signature: "", rows: null, values: /* @__PURE__ */ new Map(), pending: false });
|
|
1774
2035
|
return () => {
|
|
1775
2036
|
cancelled = true;
|
|
1776
2037
|
};
|
|
1777
2038
|
}
|
|
1778
2039
|
setSummaryState((current) => ({
|
|
1779
|
-
|
|
2040
|
+
signature: summarySignature,
|
|
1780
2041
|
rows,
|
|
1781
|
-
values: current.
|
|
2042
|
+
values: current.signature === summarySignature && current.rows === rows ? current.values : /* @__PURE__ */ new Map(),
|
|
1782
2043
|
pending: true
|
|
1783
2044
|
}));
|
|
1784
2045
|
if (loading) {
|
|
@@ -1791,13 +2052,13 @@ function Table({
|
|
|
1791
2052
|
if (cancelled) return;
|
|
1792
2053
|
const values = await calculateSummaryValues(columns, rows);
|
|
1793
2054
|
if (cancelled) return;
|
|
1794
|
-
setSummaryState({
|
|
2055
|
+
setSummaryState({ signature: summarySignature, rows, values, pending: false });
|
|
1795
2056
|
};
|
|
1796
2057
|
void run();
|
|
1797
2058
|
return () => {
|
|
1798
2059
|
cancelled = true;
|
|
1799
2060
|
};
|
|
1800
|
-
}, [
|
|
2061
|
+
}, [hasSummaryRow, loading, rows, summarySignature]);
|
|
1801
2062
|
const domRange = (0, import_react5.useMemo)(() => {
|
|
1802
2063
|
if (!isVirtualized) return { rowStart: 0, rowEnd: rows.length, columnStart: 0, columnEnd: columns.length };
|
|
1803
2064
|
const currentScroll2 = scrollRef.current;
|
|
@@ -1928,22 +2189,177 @@ function Table({
|
|
|
1928
2189
|
grid: readThemeColor(themeStyles, "--rvg-color-grid", "#e3e6e8"),
|
|
1929
2190
|
text: readThemeColor(themeStyles, "--rvg-color-text", "#202124"),
|
|
1930
2191
|
muted: readThemeColor(themeStyles, "--rvg-color-muted", "#5f6368"),
|
|
2192
|
+
icon: readThemeColor(themeStyles, "--rvg-color-icon", "#9aa0a6"),
|
|
2193
|
+
borderStrong: readThemeColor(themeStyles, "--rvg-color-border-strong", "#b8bec4"),
|
|
1931
2194
|
selection: readThemeColor(themeStyles, "--rvg-color-primary", "#1677ff"),
|
|
1932
2195
|
selectionFill: readThemeColor(themeStyles, "--rvg-color-selection-fill", "#edf4ff"),
|
|
1933
2196
|
axisSelectionFill: readThemeColor(themeStyles, "--rvg-color-axis-selection-fill", "#e8f2ff"),
|
|
1934
2197
|
rowHoverFill: readThemeColor(themeStyles, "--rvg-color-row-hover-fill", "#f6f9fc"),
|
|
1935
2198
|
editedFill: editedCellHighlightColor ?? readThemeColor(themeStyles, "--rvg-color-edited-fill", "#fff1b8"),
|
|
1936
2199
|
insertedFill: insertedRowHighlightColor ?? readThemeColor(themeStyles, "--rvg-color-inserted-fill", "#c8ead4"),
|
|
2200
|
+
columnDropTargetFill: readThemeColor(themeStyles, "--rvg-color-column-drop-target-fill", "#eeeeee"),
|
|
1937
2201
|
stripe: stripedColor ?? readThemeColor(themeStyles, "--rvg-color-stripe", "#fafbfc")
|
|
1938
2202
|
};
|
|
1939
2203
|
const scroll = scrollRef.current;
|
|
1940
2204
|
const rowScrollTop = fixedHeader ? scroll.top : Math.max(0, scroll.top - bodyTop);
|
|
1941
2205
|
const range = isVirtualized ? getViewportRange(scroll.left, rowScrollTop, viewport.width, bodyViewportHeight, rows.length, rowHeight, metrics, virtualOverscan) : { rowStart: 0, rowEnd: rows.length, columnStart: 0, columnEnd: columns.length };
|
|
1942
|
-
paintGrid({ context, width: viewport.width, height: renderHeight, pixelRatio: ratio, scrollLeft: scroll.left, scrollTop: scroll.top, rowHeight, headerHeight, headerLeafTop, headerLeafHeight, bodyTop, suppressLastRowBottomBorder: bottomSummaryHeight > 0, suppressFrameBottomBorder: bottomSummaryHeight > 0, fixedHeader, verticalBorderless: !hasVerticalBorders, striped: hasStripedRows, columnDraggable, sortState, filterValues, hoveredHeaderAction: hoveredHeaderActionRef.current, rows, columns, metrics, range, selection, editing, hoveredRowIndex: hoveredRowIndexRef.current, selectionRange, selectedRowKeys: selectedRowKeySet, selectedColumnKeys: selectedColumnKeySet, cellSpans: cellSpanLookup.covered, maxRowSpan: cellSpanLookup.maxRowSpan, highlightEditedCells: highlightsEditedCells, highlightInsertedRows: highlightsInsertedRows, insertedRowKeys: insertedRowKeySet, editedCellKeys, cellAnnotations, getRowKey, rowDragPreview, colors: themeColors });
|
|
1943
|
-
}, [bodyTop, bodyViewportHeight, bottomSummaryHeight, cellAnnotations, cellSpanLookup, columnDraggable, columns, editedCellHighlightColor, editedCellKeys, editing, renderHeight, filterValues, fixedHeader, getRowKey, hasStripedRows, hasVerticalBorders, headerDepth, headerHeight, headerLeafHeight, headerLeafTop, highlightsEditedCells, highlightsInsertedRows, insertedRowHighlightColor, insertedRowKeySet, isVirtualized, metrics, rowDragPreview, rowHeight, rows, selectedColumnKeySet, selectedRowKeySet, selection, selectionRange, sortState, stripedColor, viewport.width, virtualOverscan]);
|
|
2206
|
+
paintGrid({ context, width: viewport.width, height: renderHeight, pixelRatio: ratio, scrollLeft: scroll.left, scrollTop: scroll.top, rowHeight, headerHeight, headerLeafTop, headerLeafHeight, bodyTop, suppressLastRowBottomBorder: bottomSummaryHeight > 0, suppressFrameBottomBorder: bottomSummaryHeight > 0, fixedHeader, verticalBorderless: !hasVerticalBorders, striped: hasStripedRows, columnDraggable, sortState, filterValues, hoveredHeaderAction: hoveredHeaderActionRef.current, rows, columns, metrics, range, selection, editing, hoveredRowIndex: hoveredRowIndexRef.current, selectionRange, selectedRowKeys: selectedRowKeySet, rowSelectionMode, selectedColumnKeys: selectedColumnKeySet, cellSpans: cellSpanLookup.covered, maxRowSpan: cellSpanLookup.maxRowSpan, highlightEditedCells: highlightsEditedCells, highlightInsertedRows: highlightsInsertedRows, insertedRowKeys: insertedRowKeySet, editedCellKeys, cellAnnotations, getRowKey, rowDragPreview, columnDropTarget, colors: themeColors });
|
|
2207
|
+
}, [bodyTop, bodyViewportHeight, bottomSummaryHeight, cellAnnotations, cellSpanLookup, columnDraggable, columnDropTarget, columns, editedCellHighlightColor, editedCellKeys, editing, renderHeight, filterValues, fixedHeader, getRowKey, hasStripedRows, hasVerticalBorders, headerDepth, headerHeight, headerLeafHeight, headerLeafTop, highlightsEditedCells, highlightsInsertedRows, insertedRowHighlightColor, insertedRowKeySet, isVirtualized, metrics, rowDragPreview, rowHeight, rowSelectionMode, rows, selectedColumnKeySet, selectedRowKeySet, selection, selectionRange, sortState, stripedColor, viewport.width, virtualOverscan]);
|
|
1944
2208
|
const scheduleDraw = (0, import_react5.useCallback)(() => {
|
|
1945
2209
|
if (frameRef.current === null) frameRef.current = requestAnimationFrame(draw);
|
|
1946
2210
|
}, [draw]);
|
|
2211
|
+
const drawImmediately = (0, import_react5.useCallback)(() => {
|
|
2212
|
+
if (frameRef.current !== null) cancelAnimationFrame(frameRef.current);
|
|
2213
|
+
frameRef.current = null;
|
|
2214
|
+
draw();
|
|
2215
|
+
}, [draw]);
|
|
2216
|
+
const getSelectionHorizontalVisibility = (0, import_react5.useCallback)((scrollLeft) => {
|
|
2217
|
+
if (!selection || selectionRange) return "visible";
|
|
2218
|
+
const column = columns[selection.columnIndex];
|
|
2219
|
+
if (!column || column.fixed !== void 0) return "visible";
|
|
2220
|
+
const span = getCellSpan(selection.rowIndex, selection.columnIndex);
|
|
2221
|
+
const left = getScrollableColumnLeft(selection.columnIndex) - scrollLeft;
|
|
2222
|
+
const right = left + getCellDisplayWidth(selection.columnIndex, span?.colSpan ?? 1);
|
|
2223
|
+
if (right <= fixedWidth) return "hidden-left";
|
|
2224
|
+
if (left >= viewport.width - rightFixedWidth) return "hidden-right";
|
|
2225
|
+
return "visible";
|
|
2226
|
+
}, [columns, fixedWidth, getCellDisplayWidth, getCellSpan, getScrollableColumnLeft, rightFixedWidth, selection, selectionRange, viewport.width]);
|
|
2227
|
+
const getSelectionEdgeIndicator = (0, import_react5.useCallback)((scrollLeft, scrollTop) => {
|
|
2228
|
+
if (!selection || selectionRange) return null;
|
|
2229
|
+
const row = rows[selection.rowIndex];
|
|
2230
|
+
const metric = metrics[selection.columnIndex];
|
|
2231
|
+
const column = columns[selection.columnIndex];
|
|
2232
|
+
if (!row || !metric || !column || getRowKey(row, selection.rowIndex) !== selection.rowKey) return null;
|
|
2233
|
+
const span = getCellSpan(selection.rowIndex, selection.columnIndex);
|
|
2234
|
+
const rawLeft = column.fixed === "left" ? leftFixedOffsets.get(selection.columnIndex) ?? 0 : column.fixed === "right" ? viewport.width - (rightFixedOffsets.get(selection.columnIndex) ?? 0) - metric.width : getScrollableColumnLeft(selection.columnIndex) - scrollLeft;
|
|
2235
|
+
const rawRight = rawLeft + getCellDisplayWidth(selection.columnIndex, span?.colSpan ?? 1);
|
|
2236
|
+
const rawTop = bodyTop + selection.rowIndex * rowHeight - scrollTop;
|
|
2237
|
+
const rawBottom = rawTop + rowHeight * (span?.rowSpan ?? 1);
|
|
2238
|
+
const horizontalStart = column.fixed === void 0 ? fixedWidth : 0;
|
|
2239
|
+
const horizontalEnd = column.fixed === void 0 ? viewport.width - rightFixedWidth : viewport.width;
|
|
2240
|
+
const verticalStart = fixedHeader ? bodyTop : 0;
|
|
2241
|
+
const hiddenLeft = column.fixed === void 0 && rawRight <= horizontalStart;
|
|
2242
|
+
const hiddenRight = column.fixed === void 0 && rawLeft >= horizontalEnd;
|
|
2243
|
+
const hiddenTop = rawBottom <= verticalStart;
|
|
2244
|
+
const hiddenBottom = rawTop >= renderHeight;
|
|
2245
|
+
if (!hiddenLeft && !hiddenRight && !hiddenTop && !hiddenBottom) return null;
|
|
2246
|
+
const borderWidth = 2;
|
|
2247
|
+
const cornerLength = 10;
|
|
2248
|
+
const hitSlop = 6;
|
|
2249
|
+
const targetSize = borderWidth + hitSlop * 2;
|
|
2250
|
+
const rightBoundaryInset = rightFixedWidth > 0 && hasVerticalBorders ? 1 : 0;
|
|
2251
|
+
const markerX = hiddenLeft ? horizontalStart : horizontalEnd - borderWidth - rightBoundaryInset;
|
|
2252
|
+
const markerY = hiddenTop ? verticalStart : renderHeight - borderWidth;
|
|
2253
|
+
if (hiddenLeft || hiddenRight) {
|
|
2254
|
+
let markerTop = Math.max(rawTop - borderWidth, verticalStart);
|
|
2255
|
+
let markerBottom = Math.min(rawBottom + 1, renderHeight);
|
|
2256
|
+
const topClip = Math.max(0, verticalStart - (rawTop - borderWidth));
|
|
2257
|
+
const bottomClip = Math.max(0, rawBottom + 1 - renderHeight);
|
|
2258
|
+
if (topClip > 0 || bottomClip > 0) {
|
|
2259
|
+
const foldAtTop = topClip > 0;
|
|
2260
|
+
const fold = Math.min(cornerLength, foldAtTop ? topClip : bottomClip);
|
|
2261
|
+
if (fold > borderWidth) {
|
|
2262
|
+
const cornerWidth = fold;
|
|
2263
|
+
const cornerHeight = Math.max(cornerLength, markerBottom - markerTop);
|
|
2264
|
+
const cornerOnLeft = hiddenLeft;
|
|
2265
|
+
const shapeLeft = cornerOnLeft ? markerX : markerX + borderWidth - cornerWidth;
|
|
2266
|
+
const shapeTop = foldAtTop ? verticalStart : renderHeight - cornerHeight;
|
|
2267
|
+
return {
|
|
2268
|
+
side: `${foldAtTop ? "top" : "bottom"}-${cornerOnLeft ? "left" : "right"}`,
|
|
2269
|
+
orientation: "corner",
|
|
2270
|
+
style: {
|
|
2271
|
+
left: shapeLeft - hitSlop,
|
|
2272
|
+
top: shapeTop - hitSlop,
|
|
2273
|
+
width: cornerWidth + hitSlop * 2,
|
|
2274
|
+
height: cornerHeight + hitSlop * 2
|
|
2275
|
+
},
|
|
2276
|
+
corner: { width: cornerWidth, height: cornerHeight }
|
|
2277
|
+
};
|
|
2278
|
+
}
|
|
2279
|
+
}
|
|
2280
|
+
if (markerBottom <= markerTop) return null;
|
|
2281
|
+
return {
|
|
2282
|
+
side: hiddenLeft ? "left" : "right",
|
|
2283
|
+
orientation: "vertical",
|
|
2284
|
+
viewportEdge: hiddenLeft && horizontalStart === 0 ? "left" : hiddenRight && horizontalEnd === viewport.width ? "right" : void 0,
|
|
2285
|
+
style: {
|
|
2286
|
+
left: markerX - hitSlop,
|
|
2287
|
+
top: markerTop,
|
|
2288
|
+
width: targetSize,
|
|
2289
|
+
height: markerBottom - markerTop
|
|
2290
|
+
}
|
|
2291
|
+
};
|
|
2292
|
+
}
|
|
2293
|
+
const horizontalMarkerEnd = horizontalEnd - rightBoundaryInset;
|
|
2294
|
+
let markerLeft = Math.max(rawLeft - borderWidth, horizontalStart);
|
|
2295
|
+
let markerRight = Math.min(rawRight + 1, horizontalMarkerEnd);
|
|
2296
|
+
const leftClip = Math.max(0, horizontalStart - (rawLeft - borderWidth));
|
|
2297
|
+
const rightClip = Math.max(0, rawRight + 1 - horizontalMarkerEnd);
|
|
2298
|
+
if (leftClip > 0 || rightClip > 0) {
|
|
2299
|
+
const foldAtLeft = leftClip > 0;
|
|
2300
|
+
const fold = Math.min(cornerLength, foldAtLeft ? leftClip : rightClip);
|
|
2301
|
+
if (fold > borderWidth) {
|
|
2302
|
+
const cornerWidth = Math.max(cornerLength, markerRight - markerLeft);
|
|
2303
|
+
const cornerHeight = fold;
|
|
2304
|
+
const shapeLeft = foldAtLeft ? horizontalStart : horizontalMarkerEnd - cornerWidth;
|
|
2305
|
+
const shapeTop = hiddenTop ? verticalStart : renderHeight - cornerHeight;
|
|
2306
|
+
return {
|
|
2307
|
+
side: `${hiddenTop ? "top" : "bottom"}-${foldAtLeft ? "left" : "right"}`,
|
|
2308
|
+
orientation: "corner",
|
|
2309
|
+
style: {
|
|
2310
|
+
left: shapeLeft - hitSlop,
|
|
2311
|
+
top: shapeTop - hitSlop,
|
|
2312
|
+
width: cornerWidth + hitSlop * 2,
|
|
2313
|
+
height: cornerHeight + hitSlop * 2
|
|
2314
|
+
},
|
|
2315
|
+
corner: { width: cornerWidth, height: cornerHeight }
|
|
2316
|
+
};
|
|
2317
|
+
}
|
|
2318
|
+
}
|
|
2319
|
+
if (markerRight <= markerLeft) return null;
|
|
2320
|
+
return {
|
|
2321
|
+
side: hiddenTop ? "top" : "bottom",
|
|
2322
|
+
orientation: "horizontal",
|
|
2323
|
+
viewportEdge: hiddenTop && verticalStart === 0 ? "top" : hiddenBottom ? "bottom" : void 0,
|
|
2324
|
+
style: {
|
|
2325
|
+
left: markerLeft,
|
|
2326
|
+
top: markerY - hitSlop,
|
|
2327
|
+
width: markerRight - markerLeft,
|
|
2328
|
+
height: targetSize
|
|
2329
|
+
}
|
|
2330
|
+
};
|
|
2331
|
+
}, [bodyTop, columns, fixedHeader, fixedWidth, getCellDisplayWidth, getCellSpan, getRowKey, getScrollableColumnLeft, hasVerticalBorders, leftFixedOffsets, metrics, renderHeight, rightFixedOffsets, rightFixedWidth, rowHeight, rows, selection, selectionRange, viewport.width]);
|
|
2332
|
+
const syncSelectionEdgeTarget = (0, import_react5.useCallback)((scrollLeft, scrollTop) => {
|
|
2333
|
+
const target = selectionEdgeTargetRef.current;
|
|
2334
|
+
if (!target) return;
|
|
2335
|
+
const indicator = getSelectionEdgeIndicator(scrollLeft, scrollTop);
|
|
2336
|
+
if (!indicator) {
|
|
2337
|
+
target.style.visibility = "hidden";
|
|
2338
|
+
return;
|
|
2339
|
+
}
|
|
2340
|
+
const orientationChanged = !target.classList.contains(`is-${indicator.orientation}`);
|
|
2341
|
+
target.className = `rvg-selection-edge-target is-${indicator.orientation} is-${indicator.side}${indicator.viewportEdge ? ` is-viewport-${indicator.viewportEdge}` : ""}${orientationChanged ? " is-shape-syncing" : ""}`;
|
|
2342
|
+
target.style.left = `${Number(indicator.style.left)}px`;
|
|
2343
|
+
target.style.top = `${Number(indicator.style.top)}px`;
|
|
2344
|
+
target.style.width = `${Number(indicator.style.width)}px`;
|
|
2345
|
+
target.style.height = `${Number(indicator.style.height)}px`;
|
|
2346
|
+
if (indicator.corner) {
|
|
2347
|
+
target.style.setProperty("--rvg-corner-width", `${indicator.corner.width}px`);
|
|
2348
|
+
target.style.setProperty("--rvg-corner-height", `${indicator.corner.height}px`);
|
|
2349
|
+
target.style.setProperty("--rvg-corner-hover-width-extension", "4px");
|
|
2350
|
+
target.style.setProperty("--rvg-corner-hover-height-extension", "4px");
|
|
2351
|
+
} else {
|
|
2352
|
+
target.style.removeProperty("--rvg-corner-width");
|
|
2353
|
+
target.style.removeProperty("--rvg-corner-height");
|
|
2354
|
+
target.style.removeProperty("--rvg-corner-hover-width-extension");
|
|
2355
|
+
target.style.removeProperty("--rvg-corner-hover-height-extension");
|
|
2356
|
+
}
|
|
2357
|
+
target.style.visibility = "visible";
|
|
2358
|
+
if (orientationChanged) {
|
|
2359
|
+
void target.offsetWidth;
|
|
2360
|
+
target.classList.remove("is-shape-syncing");
|
|
2361
|
+
}
|
|
2362
|
+
}, [getSelectionEdgeIndicator]);
|
|
1947
2363
|
(0, import_react5.useLayoutEffect)(() => {
|
|
1948
2364
|
const element = scrollerRef.current;
|
|
1949
2365
|
if (!element) return;
|
|
@@ -1970,11 +2386,7 @@ function Table({
|
|
|
1970
2386
|
}
|
|
1971
2387
|
};
|
|
1972
2388
|
}, [scheduleDraw]);
|
|
1973
|
-
(0, import_react5.useEffect)(() => {
|
|
1974
|
-
setDisplaySortState(sortState);
|
|
1975
|
-
}, [sortState]);
|
|
1976
2389
|
(0, import_react5.useEffect)(() => () => {
|
|
1977
|
-
if (sortDebounceRef.current !== null) clearTimeout(sortDebounceRef.current);
|
|
1978
2390
|
if (textFrameRef.current !== null) cancelAnimationFrame(textFrameRef.current);
|
|
1979
2391
|
if (toastTimerRef.current !== null) clearTimeout(toastTimerRef.current);
|
|
1980
2392
|
if (verticalScrollbarVisibilityTimerRef.current !== null) clearTimeout(verticalScrollbarVisibilityTimerRef.current);
|
|
@@ -2194,7 +2606,13 @@ function Table({
|
|
|
2194
2606
|
}
|
|
2195
2607
|
const nextThumbLeft = Math.max(0, Math.min(trackWidth - thumbWidth, event.clientX - trackRect.left - thumbWidth / 2));
|
|
2196
2608
|
const maxThumbLeft = Math.max(1, trackWidth - thumbWidth);
|
|
2197
|
-
scroller.scrollLeft
|
|
2609
|
+
const previousScrollLeft = scroller.scrollLeft;
|
|
2610
|
+
const nextScrollLeft = nextThumbLeft / maxThumbLeft * maxScrollLeft;
|
|
2611
|
+
const visibilityChanged = getSelectionHorizontalVisibility(previousScrollLeft) !== getSelectionHorizontalVisibility(nextScrollLeft);
|
|
2612
|
+
scroller.scrollLeft = nextScrollLeft;
|
|
2613
|
+
scrollRef.current = { left: scroller.scrollLeft, top: scroller.scrollTop };
|
|
2614
|
+
syncSelectionEdgeTarget(scroller.scrollLeft, scroller.scrollTop);
|
|
2615
|
+
if (visibilityChanged) drawImmediately();
|
|
2198
2616
|
updateCustomScrollbars();
|
|
2199
2617
|
horizontalScrollbarDragRef.current = {
|
|
2200
2618
|
pointerId: event.pointerId,
|
|
@@ -2204,7 +2622,7 @@ function Table({
|
|
|
2204
2622
|
thumbWidth,
|
|
2205
2623
|
maxScrollLeft
|
|
2206
2624
|
};
|
|
2207
|
-
}, [showCustomScrollbar, updateCustomScrollbars]);
|
|
2625
|
+
}, [drawImmediately, getSelectionHorizontalVisibility, showCustomScrollbar, syncSelectionEdgeTarget, updateCustomScrollbars]);
|
|
2208
2626
|
const handleHorizontalScrollbarPointerMove = (0, import_react5.useCallback)((event) => {
|
|
2209
2627
|
const drag = horizontalScrollbarDragRef.current;
|
|
2210
2628
|
const scroller = scrollerRef.current;
|
|
@@ -2212,9 +2630,15 @@ function Table({
|
|
|
2212
2630
|
event.preventDefault();
|
|
2213
2631
|
const maxThumbLeft = Math.max(1, drag.trackWidth - drag.thumbWidth);
|
|
2214
2632
|
const nextThumbLeft = Math.max(0, Math.min(maxThumbLeft, drag.startLeft + event.clientX - drag.startX));
|
|
2215
|
-
|
|
2633
|
+
const previousScrollLeft = scroller.scrollLeft;
|
|
2634
|
+
const nextScrollLeft = nextThumbLeft / maxThumbLeft * drag.maxScrollLeft;
|
|
2635
|
+
const visibilityChanged = getSelectionHorizontalVisibility(previousScrollLeft) !== getSelectionHorizontalVisibility(nextScrollLeft);
|
|
2636
|
+
scroller.scrollLeft = nextScrollLeft;
|
|
2637
|
+
scrollRef.current = { left: scroller.scrollLeft, top: scroller.scrollTop };
|
|
2638
|
+
syncSelectionEdgeTarget(scroller.scrollLeft, scroller.scrollTop);
|
|
2639
|
+
if (visibilityChanged) drawImmediately();
|
|
2216
2640
|
updateCustomScrollbars();
|
|
2217
|
-
}, [updateCustomScrollbars]);
|
|
2641
|
+
}, [drawImmediately, getSelectionHorizontalVisibility, syncSelectionEdgeTarget, updateCustomScrollbars]);
|
|
2218
2642
|
const handleHorizontalScrollbarPointerUp = (0, import_react5.useCallback)((event) => {
|
|
2219
2643
|
const drag = horizontalScrollbarDragRef.current;
|
|
2220
2644
|
if (!drag || drag.pointerId !== event.pointerId) return;
|
|
@@ -2229,6 +2653,7 @@ function Table({
|
|
|
2229
2653
|
const scrollDeltaX = element.scrollLeft - previousScroll.left;
|
|
2230
2654
|
const scrollDeltaY = element.scrollTop - previousScroll.top;
|
|
2231
2655
|
scrollRef.current = { left: element.scrollLeft, top: element.scrollTop };
|
|
2656
|
+
syncSelectionEdgeTarget(element.scrollLeft, element.scrollTop);
|
|
2232
2657
|
const focus = selectionFocusRef.current;
|
|
2233
2658
|
if (focus && selection && !selectionRange) {
|
|
2234
2659
|
const row = rows[selection.rowIndex];
|
|
@@ -2250,9 +2675,9 @@ function Table({
|
|
|
2250
2675
|
focus.style.display = "none";
|
|
2251
2676
|
} else {
|
|
2252
2677
|
const borderWidth = 2;
|
|
2253
|
-
const left = Math.round(Math.max(rawLeft - borderWidth, horizontalStart
|
|
2678
|
+
const left = Math.round(Math.max(rawLeft - borderWidth, horizontalStart));
|
|
2254
2679
|
const right = Math.round(Math.min(rawRight + 1, horizontalEnd, viewport.width));
|
|
2255
|
-
const top = Math.round(Math.max(rawTop - borderWidth, verticalStart
|
|
2680
|
+
const top = Math.round(Math.max(rawTop - borderWidth, verticalStart));
|
|
2256
2681
|
const bottom = Math.round(Math.min(rawBottom + 1, renderHeight));
|
|
2257
2682
|
focus.style.display = "block";
|
|
2258
2683
|
focus.style.left = `${left}px`;
|
|
@@ -2282,7 +2707,7 @@ function Table({
|
|
|
2282
2707
|
setHoveredCellTooltip(null);
|
|
2283
2708
|
scheduleDraw();
|
|
2284
2709
|
setEditing(null);
|
|
2285
|
-
}, [bodyTop, columns, renderHeight, fixedHeader, fixedWidth, getCellDisplayWidth, getCellSpan, getRowKey, getScrollableColumnLeft, metrics, rightFixedOffsets, rightFixedWidth, rowHeight, rows, scheduleDraw, selection, selectionRange, showCustomScrollbar, updateCustomScrollbars, viewport.width]);
|
|
2710
|
+
}, [bodyTop, columns, renderHeight, fixedHeader, fixedWidth, getCellDisplayWidth, getCellSpan, getRowKey, getScrollableColumnLeft, metrics, rightFixedOffsets, rightFixedWidth, rowHeight, rows, scheduleDraw, selection, selectionRange, showCustomScrollbar, syncSelectionEdgeTarget, updateCustomScrollbars, viewport.width]);
|
|
2286
2711
|
const locateColumn = (0, import_react5.useCallback)((clientX) => {
|
|
2287
2712
|
const canvas = canvasRef.current;
|
|
2288
2713
|
if (!canvas) return -1;
|
|
@@ -2336,12 +2761,12 @@ function Table({
|
|
|
2336
2761
|
const localX = clientX - canvasRef.current.getBoundingClientRect().left;
|
|
2337
2762
|
const columnRight = getDisplayedColumnLeft(columnIndex) + metrics[columnIndex].width;
|
|
2338
2763
|
const visibleActions = getVisibleHeaderActions(column, metrics[columnIndex].width, columnDraggable, measureHeaderTitleWidth(columnIndex));
|
|
2339
|
-
let right = columnRight - (visibleActions.drag ?
|
|
2764
|
+
let right = columnRight - (visibleActions.drag ? HEADER_ACTION_SLOT_WIDTH : 2);
|
|
2340
2765
|
if (visibleActions.sort) {
|
|
2341
|
-
if (localX >= right -
|
|
2342
|
-
right -=
|
|
2766
|
+
if (localX >= right - HEADER_ACTION_SLOT_WIDTH && localX < right) return "sort";
|
|
2767
|
+
right -= HEADER_ACTION_SLOT_WIDTH;
|
|
2343
2768
|
}
|
|
2344
|
-
if (visibleActions.filter && localX >= right -
|
|
2769
|
+
if (visibleActions.filter && localX >= right - HEADER_ACTION_SLOT_WIDTH && localX < right) return "filter";
|
|
2345
2770
|
return null;
|
|
2346
2771
|
}, [columnDraggable, columns, getDisplayedColumnLeft, measureHeaderTitleWidth, metrics]);
|
|
2347
2772
|
const isHeaderTitleTruncated = (0, import_react5.useCallback)((columnIndex) => {
|
|
@@ -2351,7 +2776,7 @@ function Table({
|
|
|
2351
2776
|
const metric = metrics[columnIndex];
|
|
2352
2777
|
const titleWidth = measureHeaderTitleWidth(columnIndex);
|
|
2353
2778
|
const visibleActions = getVisibleHeaderActions(column, metric.width, columnDraggable, titleWidth);
|
|
2354
|
-
const actionWidth = (Number(visibleActions.drag) + Number(visibleActions.filter) + Number(visibleActions.sort)) *
|
|
2779
|
+
const actionWidth = (Number(visibleActions.drag) + Number(visibleActions.filter) + Number(visibleActions.sort)) * HEADER_ACTION_SLOT_WIDTH;
|
|
2355
2780
|
return getHeaderTitleRequiredWidth(column, titleWidth) > Math.max(0, metric.width - actionWidth);
|
|
2356
2781
|
}, [columnDraggable, columns, measureHeaderTitleWidth, metrics]);
|
|
2357
2782
|
const locateHeaderDragHandle = (0, import_react5.useCallback)((clientX, columnIndex) => {
|
|
@@ -2370,6 +2795,30 @@ function Table({
|
|
|
2370
2795
|
return fixedSide === "left" ? leftFixedOffsets.get(cell.startIndex) ?? 0 : fixedSide === "right" ? viewport.width - (rightFixedOffsets.get(cell.startIndex) ?? 0) - startMetric.width : getScrollableColumnLeft(cell.startIndex) - scrollRef.current.left;
|
|
2371
2796
|
}, [columns, getScrollableColumnLeft, leftFixedOffsets, metrics, rightFixedOffsets, viewport.width]);
|
|
2372
2797
|
const getHeaderCellWidth = (0, import_react5.useCallback)((cell) => cell.leaf ? metrics[cell.startIndex]?.width ?? 0 : getCellDisplayWidth(cell.startIndex, cell.endIndex - cell.startIndex + 1), [getCellDisplayWidth, metrics]);
|
|
2798
|
+
const getHeaderCellEdgeFromMetrics = (0, import_react5.useCallback)((startIndex, endIndex, edge, nextMetrics) => {
|
|
2799
|
+
const fixedSide = columns[startIndex]?.fixed;
|
|
2800
|
+
const width2 = nextMetrics.slice(startIndex, endIndex + 1).reduce((total, metric) => total + metric.width, 0);
|
|
2801
|
+
let left;
|
|
2802
|
+
if (fixedSide === "left") {
|
|
2803
|
+
left = 0;
|
|
2804
|
+
for (let index = 0; index < startIndex; index += 1) {
|
|
2805
|
+
if (columns[index].fixed === "left") left += nextMetrics[index]?.width ?? 0;
|
|
2806
|
+
}
|
|
2807
|
+
} else if (fixedSide === "right") {
|
|
2808
|
+
let rightOffset = 0;
|
|
2809
|
+
for (let index = columns.length - 1; index > startIndex; index -= 1) {
|
|
2810
|
+
if (columns[index].fixed === "right") rightOffset += nextMetrics[index]?.width ?? 0;
|
|
2811
|
+
}
|
|
2812
|
+
left = viewport.width - rightOffset - width2;
|
|
2813
|
+
} else {
|
|
2814
|
+
left = 0;
|
|
2815
|
+
for (let index = 0; index < startIndex; index += 1) {
|
|
2816
|
+
if (columns[index].fixed === void 0) left += nextMetrics[index]?.width ?? 0;
|
|
2817
|
+
}
|
|
2818
|
+
left += fixedWidth - scrollRef.current.left;
|
|
2819
|
+
}
|
|
2820
|
+
return left + (edge === "right" ? width2 : 0);
|
|
2821
|
+
}, [columns, fixedWidth, viewport.width]);
|
|
2373
2822
|
const locateHeaderResizeHit = (0, import_react5.useCallback)((clientX, clientY) => {
|
|
2374
2823
|
if (!columnResizable || !canvasRef.current) return null;
|
|
2375
2824
|
const rect = canvasRef.current.getBoundingClientRect();
|
|
@@ -2380,6 +2829,7 @@ function Table({
|
|
|
2380
2829
|
const level = getHeaderLevelAtY(localY, headerY);
|
|
2381
2830
|
let closest = null;
|
|
2382
2831
|
let distance = 6;
|
|
2832
|
+
let priority = -1;
|
|
2383
2833
|
for (const cell of headerCells) {
|
|
2384
2834
|
if (cell.level !== level) continue;
|
|
2385
2835
|
if (columns[cell.startIndex]?.rowSelection || columns[cell.startIndex]?.rowDragHandle || columns[cell.startIndex]?.rowNumber) continue;
|
|
@@ -2387,8 +2837,10 @@ function Table({
|
|
|
2387
2837
|
const edge = fixedSide === "right" && cell.leaf ? "left" : "right";
|
|
2388
2838
|
const edgeX = getHeaderCellLeft(cell) + (edge === "right" ? getHeaderCellWidth(cell) : 0);
|
|
2389
2839
|
const nextDistance = Math.abs(localX - edgeX);
|
|
2390
|
-
|
|
2840
|
+
const nextPriority = fixedSide === "right" ? 2 : fixedSide === "left" ? 1 : 0;
|
|
2841
|
+
if (nextDistance < distance || nextDistance === distance && nextPriority > priority) {
|
|
2391
2842
|
distance = nextDistance;
|
|
2843
|
+
priority = nextPriority;
|
|
2392
2844
|
closest = { cell, edge };
|
|
2393
2845
|
}
|
|
2394
2846
|
}
|
|
@@ -2480,6 +2932,7 @@ function Table({
|
|
|
2480
2932
|
}
|
|
2481
2933
|
const sourceIndex = headerDragCell.startIndex;
|
|
2482
2934
|
columnDragPreviewRef.current = { sourceIndex, targetIndex: sourceIndex };
|
|
2935
|
+
validColumnDropRef.current = null;
|
|
2483
2936
|
return {
|
|
2484
2937
|
type: "table-column",
|
|
2485
2938
|
sourceIndex,
|
|
@@ -2490,13 +2943,26 @@ function Table({
|
|
|
2490
2943
|
fixed: columns[headerDragCell.startIndex]?.fixed
|
|
2491
2944
|
};
|
|
2492
2945
|
},
|
|
2493
|
-
onGenerateDragPreview: ({ nativeSetDragImage, source }) => {
|
|
2946
|
+
onGenerateDragPreview: ({ nativeSetDragImage, source, location }) => {
|
|
2494
2947
|
const sourceIndex = Number(source.data.sourceIndex);
|
|
2948
|
+
const canvasRect = canvas.getBoundingClientRect();
|
|
2949
|
+
const input = location.current.input;
|
|
2950
|
+
const previewOffset = source.data.type === "table-row" ? {
|
|
2951
|
+
x: Math.max(0, Math.min(canvasRect.width, input.clientX - canvasRect.left)) + 2,
|
|
2952
|
+
y: Math.max(0, Math.min(rowHeight, input.clientY - canvasRect.top - bodyTop - sourceIndex * rowHeight + scrollRef.current.top)) + 2
|
|
2953
|
+
} : {
|
|
2954
|
+
x: Math.max(0, Math.min(metrics[sourceIndex].width, input.clientX - canvasRect.left - getDisplayedColumnLeft(sourceIndex))),
|
|
2955
|
+
y: Math.max(0, Math.min(canvasRect.height, input.clientY - canvasRect.top))
|
|
2956
|
+
};
|
|
2495
2957
|
(0, import_set_custom_native_drag_preview.setCustomNativeDragPreview)({
|
|
2496
2958
|
nativeSetDragImage,
|
|
2959
|
+
getOffset: () => previewOffset,
|
|
2497
2960
|
render: ({ container }) => {
|
|
2498
|
-
const canvasRect = canvas.getBoundingClientRect();
|
|
2499
2961
|
if (source.data.type === "table-row") {
|
|
2962
|
+
const frame = document.createElement("div");
|
|
2963
|
+
frame.className = "rvg-row-drag-preview-frame";
|
|
2964
|
+
frame.style.width = `${canvasRect.width + 4}px`;
|
|
2965
|
+
frame.style.height = `${rowHeight + 4}px`;
|
|
2500
2966
|
const preview2 = document.createElement("div");
|
|
2501
2967
|
preview2.className = "rvg-row-drag-preview";
|
|
2502
2968
|
preview2.style.width = `${canvasRect.width}px`;
|
|
@@ -2522,10 +2988,14 @@ function Table({
|
|
|
2522
2988
|
} else {
|
|
2523
2989
|
cell.textContent = getCellLabel(sourceIndex, columnIndex);
|
|
2524
2990
|
}
|
|
2991
|
+
if (selection?.rowKey === rowKey2 && selection.columnKey === column2.key) {
|
|
2992
|
+
cell.classList.add("is-selected");
|
|
2993
|
+
}
|
|
2525
2994
|
preview2.appendChild(cell);
|
|
2526
2995
|
});
|
|
2527
|
-
|
|
2528
|
-
|
|
2996
|
+
frame.appendChild(preview2);
|
|
2997
|
+
container.appendChild(frame);
|
|
2998
|
+
return () => frame.remove();
|
|
2529
2999
|
}
|
|
2530
3000
|
const preview = document.createElement("div");
|
|
2531
3001
|
preview.className = "rvg-column-drag-preview";
|
|
@@ -2539,6 +3009,29 @@ function Table({
|
|
|
2539
3009
|
header.style.height = `${headerHeight}px`;
|
|
2540
3010
|
header.style.justifyContent = column.align === "right" ? "flex-end" : column.align === "center" ? "center" : "flex-start";
|
|
2541
3011
|
header.textContent = column.title;
|
|
3012
|
+
const visibleActions = getVisibleHeaderActions(column, columnWidth, columnDraggable, measureHeaderTitleWidth(sourceIndex));
|
|
3013
|
+
let actionRight = 2;
|
|
3014
|
+
if (visibleActions.drag) {
|
|
3015
|
+
const icon = createHeaderDragHandleSvg();
|
|
3016
|
+
icon.classList.add("rvg-preview-header-icon");
|
|
3017
|
+
icon.style.right = `${actionRight}px`;
|
|
3018
|
+
header.appendChild(icon);
|
|
3019
|
+
actionRight += HEADER_ACTION_SLOT_WIDTH;
|
|
3020
|
+
}
|
|
3021
|
+
if (visibleActions.sort) {
|
|
3022
|
+
const direction = sortState?.columnKey === column.key ? sortState.direction : null;
|
|
3023
|
+
const icon = createHeaderSortSvg(direction);
|
|
3024
|
+
icon.classList.add("rvg-preview-header-icon");
|
|
3025
|
+
icon.style.right = `${actionRight}px`;
|
|
3026
|
+
header.appendChild(icon);
|
|
3027
|
+
actionRight += HEADER_ACTION_SLOT_WIDTH;
|
|
3028
|
+
}
|
|
3029
|
+
if (visibleActions.filter) {
|
|
3030
|
+
const icon = createHeaderSearchSvg(Boolean(filterValues[column.key]));
|
|
3031
|
+
icon.classList.add("rvg-preview-header-icon", "rvg-preview-header-search-icon");
|
|
3032
|
+
icon.style.right = `${actionRight}px`;
|
|
3033
|
+
header.appendChild(icon);
|
|
3034
|
+
}
|
|
2542
3035
|
preview.appendChild(header);
|
|
2543
3036
|
for (let rowIndex = domRange.rowStart; rowIndex < domRange.rowEnd; rowIndex += 1) {
|
|
2544
3037
|
const row = rows[rowIndex];
|
|
@@ -2567,6 +3060,8 @@ function Table({
|
|
|
2567
3060
|
},
|
|
2568
3061
|
onDragStart: ({ source }) => {
|
|
2569
3062
|
suppressClickRef.current = true;
|
|
3063
|
+
hideDragTooltips();
|
|
3064
|
+
document.documentElement.classList.add("rvg-is-dragging");
|
|
2570
3065
|
canvas.style.cursor = "move";
|
|
2571
3066
|
if (source.data.type === "table-row") {
|
|
2572
3067
|
const sourceIndex = Number(source.data.sourceIndex);
|
|
@@ -2592,30 +3087,66 @@ function Table({
|
|
|
2592
3087
|
}
|
|
2593
3088
|
const targetIndex = Number(target?.targetIndex);
|
|
2594
3089
|
if (!Number.isInteger(targetIndex) || target?.headerKind !== source.data.headerKind || target?.parentKey !== source.data.parentKey || target?.fixed !== source.data.fixed) {
|
|
3090
|
+
validColumnDropRef.current = null;
|
|
3091
|
+
setColumnDropTarget(null);
|
|
2595
3092
|
setDragGuide(null);
|
|
2596
3093
|
return;
|
|
2597
3094
|
}
|
|
2598
3095
|
const edge = target?.columnEdge;
|
|
2599
3096
|
const destinationIndex = getColumnDropIndex(sourceIndex, targetIndex, edge);
|
|
2600
3097
|
columnDragPreviewRef.current = { sourceIndex, targetIndex: destinationIndex };
|
|
3098
|
+
if (destinationIndex === sourceIndex) {
|
|
3099
|
+
validColumnDropRef.current = null;
|
|
3100
|
+
setColumnDropTarget(null);
|
|
3101
|
+
setDragGuide(null);
|
|
3102
|
+
return;
|
|
3103
|
+
}
|
|
3104
|
+
validColumnDropRef.current = {
|
|
3105
|
+
sourceIndex,
|
|
3106
|
+
targetIndex: destinationIndex,
|
|
3107
|
+
rawTargetIndex: targetIndex,
|
|
3108
|
+
targetKey: String(target.targetKey),
|
|
3109
|
+
headerKind: source.data.headerKind === "group" ? "group" : "column",
|
|
3110
|
+
parentKey: typeof source.data.parentKey === "string" ? source.data.parentKey : void 0,
|
|
3111
|
+
fixed: source.data.fixed === "left" || source.data.fixed === "right" ? source.data.fixed : void 0,
|
|
3112
|
+
columnEdge: edge === "right" ? "right" : "left"
|
|
3113
|
+
};
|
|
3114
|
+
const siblingCells = headerCells.filter((cell) => cell.level === Number(source.data.headerLevel) && (cell.leaf ? "column" : "group") === source.data.headerKind && cell.parentKey === source.data.parentKey && columns[cell.startIndex]?.fixed === source.data.fixed);
|
|
3115
|
+
const targetEndIndex = Number.isInteger(target?.targetEndIndex) ? Number(target.targetEndIndex) : targetIndex;
|
|
3116
|
+
const hoveredTargetCell = siblingCells.find((cell) => cell.startIndex === targetIndex && cell.endIndex === targetEndIndex);
|
|
3117
|
+
if (!hoveredTargetCell) {
|
|
3118
|
+
validColumnDropRef.current = null;
|
|
3119
|
+
setColumnDropTarget(null);
|
|
3120
|
+
setDragGuide(null);
|
|
3121
|
+
return;
|
|
3122
|
+
}
|
|
3123
|
+
const highlightedCell = edge === "right" ? hoveredTargetCell : siblingCells.filter((cell) => cell.endIndex < hoveredTargetCell.startIndex).sort((left, right) => right.endIndex - left.endIndex)[0] ?? hoveredTargetCell;
|
|
3124
|
+
setColumnDropTarget({ startIndex: highlightedCell.startIndex, endIndex: highlightedCell.endIndex });
|
|
2601
3125
|
const targetLeft = Number(target?.targetLeft);
|
|
2602
3126
|
const targetWidth = Number(target?.targetWidth);
|
|
3127
|
+
if (!Number.isFinite(targetLeft) || !Number.isFinite(targetWidth)) {
|
|
3128
|
+
validColumnDropRef.current = null;
|
|
3129
|
+
setColumnDropTarget(null);
|
|
3130
|
+
setDragGuide(null);
|
|
3131
|
+
return;
|
|
3132
|
+
}
|
|
2603
3133
|
const guideTop = headerRowOffsets[Number(source.data.headerLevel)] ?? 0;
|
|
2604
3134
|
setDragGuide(edge === "right" ? targetLeft + targetWidth : targetLeft, guideTop);
|
|
2605
3135
|
},
|
|
2606
3136
|
onDrop: ({ source, location }) => {
|
|
3137
|
+
document.documentElement.classList.remove("rvg-is-dragging");
|
|
2607
3138
|
const target = location.current.dropTargets[0]?.data;
|
|
2608
3139
|
const sourceIndex = Number(source.data.sourceIndex);
|
|
2609
3140
|
if (source.data.type === "table-row") {
|
|
2610
|
-
const
|
|
2611
|
-
let
|
|
2612
|
-
if (sourceIndex <
|
|
2613
|
-
|
|
3141
|
+
const rawTargetIndex = Number(target?.targetIndex);
|
|
3142
|
+
let targetIndex = rawTargetIndex + (target?.rowEdge === "bottom" ? 1 : 0);
|
|
3143
|
+
if (sourceIndex < targetIndex) targetIndex -= 1;
|
|
3144
|
+
targetIndex = Math.max(0, Math.min(rows.length - 1, targetIndex));
|
|
2614
3145
|
scrollerRef.current?.classList.add("rvg-row-drop-settling");
|
|
2615
3146
|
setRowDragPreview(null);
|
|
2616
3147
|
setRowDragGuide(null);
|
|
2617
3148
|
canvas.style.cursor = "default";
|
|
2618
|
-
if (Number.isInteger(
|
|
3149
|
+
if (Number.isInteger(rawTargetIndex) && sourceIndex !== targetIndex) applyRowOrder(sourceIndex, targetIndex);
|
|
2619
3150
|
requestAnimationFrame(() => {
|
|
2620
3151
|
requestAnimationFrame(() => scrollerRef.current?.classList.remove("rvg-row-drop-settling"));
|
|
2621
3152
|
});
|
|
@@ -2624,21 +3155,22 @@ function Table({
|
|
|
2624
3155
|
}, 0);
|
|
2625
3156
|
return;
|
|
2626
3157
|
}
|
|
2627
|
-
const
|
|
2628
|
-
const targetIndex = columnDragPreviewRef.current?.targetIndex ?? (Number.isInteger(rawTargetIndex) ? getColumnDropIndex(sourceIndex, rawTargetIndex, target?.columnEdge) : rawTargetIndex);
|
|
3158
|
+
const validDrop = validColumnDropRef.current;
|
|
2629
3159
|
canvas.style.cursor = "default";
|
|
2630
3160
|
setDragGuide(null);
|
|
3161
|
+
setColumnDropTarget(null);
|
|
2631
3162
|
columnDragPreviewRef.current = null;
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
3163
|
+
validColumnDropRef.current = null;
|
|
3164
|
+
if (validDrop) {
|
|
3165
|
+
applyColumnOrder(
|
|
3166
|
+
validDrop.sourceIndex - utilityColumnCount,
|
|
3167
|
+
validDrop.targetIndex - utilityColumnCount,
|
|
2636
3168
|
{
|
|
2637
|
-
type:
|
|
3169
|
+
type: validDrop.headerKind,
|
|
2638
3170
|
sourceKey: String(source.data.sourceKey),
|
|
2639
|
-
targetKey:
|
|
2640
|
-
parentKey:
|
|
2641
|
-
placement: getColumnDropPlacement(sourceIndex, rawTargetIndex,
|
|
3171
|
+
targetKey: validDrop.targetKey,
|
|
3172
|
+
parentKey: validDrop.parentKey,
|
|
3173
|
+
placement: getColumnDropPlacement(validDrop.sourceIndex, validDrop.rawTargetIndex, validDrop.columnEdge)
|
|
2642
3174
|
}
|
|
2643
3175
|
);
|
|
2644
3176
|
}
|
|
@@ -2650,6 +3182,7 @@ function Table({
|
|
|
2650
3182
|
const cleanupDrop = (0, import_adapter.dropTargetForElements)({
|
|
2651
3183
|
element: canvas,
|
|
2652
3184
|
canDrop: ({ source }) => source.data.type === "table-column" || source.data.type === "table-row",
|
|
3185
|
+
getDropEffect: () => "move",
|
|
2653
3186
|
getData: ({ input, element, source }) => {
|
|
2654
3187
|
if (source.data.type === "table-row") {
|
|
2655
3188
|
const targetIndex2 = locateRow(input.clientY);
|
|
@@ -2658,7 +3191,8 @@ function Table({
|
|
|
2658
3191
|
const rowEdge = input.clientY - canvas.getBoundingClientRect().top < rowTop + rowHeight / 2 ? "top" : "bottom";
|
|
2659
3192
|
return (0, import_closest_edge.attachClosestEdge)({ targetIndex: targetIndex2, rowEdge }, { element, input, allowedEdges: ["top", "bottom"] });
|
|
2660
3193
|
}
|
|
2661
|
-
const
|
|
3194
|
+
const hoveredColumnIndex = locateColumn(input.clientX);
|
|
3195
|
+
const targetCell = locateHeaderCell(input.clientX, input.clientY) ?? headerCells.find((cell) => hoveredColumnIndex >= cell.startIndex && hoveredColumnIndex <= cell.endIndex && cell.level === Number(source.data.headerLevel) && (cell.leaf ? "column" : "group") === source.data.headerKind && cell.parentKey === source.data.parentKey);
|
|
2662
3196
|
if (!targetCell) return { targetIndex: -1 };
|
|
2663
3197
|
let targetIndex = targetCell.startIndex;
|
|
2664
3198
|
const targetFixed = columns[targetCell.startIndex]?.fixed;
|
|
@@ -2675,6 +3209,7 @@ function Table({
|
|
|
2675
3209
|
const columnEdge = input.clientX - canvas.getBoundingClientRect().left < left + targetWidth / 2 ? "left" : "right";
|
|
2676
3210
|
return (0, import_closest_edge.attachClosestEdge)({
|
|
2677
3211
|
targetIndex,
|
|
3212
|
+
targetEndIndex: targetCell.endIndex,
|
|
2678
3213
|
targetKey: targetCell.key,
|
|
2679
3214
|
parentKey: targetCell.parentKey,
|
|
2680
3215
|
headerKind,
|
|
@@ -2686,10 +3221,11 @@ function Table({
|
|
|
2686
3221
|
}
|
|
2687
3222
|
});
|
|
2688
3223
|
return () => {
|
|
3224
|
+
document.documentElement.classList.remove("rvg-is-dragging");
|
|
2689
3225
|
cleanupDrag();
|
|
2690
3226
|
cleanupDrop();
|
|
2691
3227
|
};
|
|
2692
|
-
}, [bodyTop, columnDraggable, columns, fixedHeader, getCellLabel, getDisplayedColumnLeft, getHeaderCellWidth, getRowKey, headerHeight, locateColumn, locateHeaderCell, locateHeaderCellDragHandle, locateHeaderResizeCell, locateRow,
|
|
3228
|
+
}, [applyColumnOrder, applyRowOrder, bodyTop, columnDraggable, columns, filterValues, fixedHeader, getCellLabel, getDisplayedColumnLeft, getHeaderCellWidth, getRowKey, headerCells, headerHeight, hideDragTooltips, locateColumn, locateHeaderCell, locateHeaderCellDragHandle, locateHeaderResizeCell, locateRow, measureHeaderTitleWidth, metrics, rowDraggable, rowHeight, rows, selectedRowKeySet, selection, setDragGuide, setRowDragGuide, sortState, utilityColumnCount]);
|
|
2693
3229
|
const locateCell = (0, import_react5.useCallback)((clientX, clientY) => {
|
|
2694
3230
|
const canvas = canvasRef.current;
|
|
2695
3231
|
if (!canvas) return null;
|
|
@@ -2997,18 +3533,28 @@ function Table({
|
|
|
2997
3533
|
const editorStyle = (0, import_react5.useMemo)(() => {
|
|
2998
3534
|
if (!editing) return void 0;
|
|
2999
3535
|
const metric = metrics[editing.columnIndex];
|
|
3000
|
-
const
|
|
3536
|
+
const column = columns[editing.columnIndex];
|
|
3537
|
+
if (!metric || !column) return void 0;
|
|
3538
|
+
const fixedSide = column.fixed;
|
|
3001
3539
|
const span = getCellSpan(editing.rowIndex, editing.columnIndex);
|
|
3002
3540
|
const cellWidth = getCellDisplayWidth(editing.columnIndex, span?.colSpan ?? 1);
|
|
3003
3541
|
const cellHeight = rowHeight * (span?.rowSpan ?? 1);
|
|
3004
3542
|
const cellLeft = fixedSide === "left" ? leftFixedOffsets.get(editing.columnIndex) ?? 0 : fixedSide === "right" ? viewport.width - (rightFixedOffsets.get(editing.columnIndex) ?? 0) - metric.width : getScrollableColumnLeft(editing.columnIndex) - scrollRef.current.left;
|
|
3543
|
+
const cellTop = bodyTop + editing.rowIndex * rowHeight - scrollRef.current.top;
|
|
3544
|
+
const horizontalStart = fixedSide === void 0 ? fixedWidth : 0;
|
|
3545
|
+
const horizontalEnd = fixedSide === void 0 ? viewport.width - rightFixedWidth : viewport.width;
|
|
3546
|
+
const verticalStart = fixedHeader ? bodyTop : 0;
|
|
3547
|
+
const visibleLeft = Math.max(cellLeft, horizontalStart);
|
|
3548
|
+
const visibleRight = Math.min(cellLeft + cellWidth, horizontalEnd, viewport.width);
|
|
3549
|
+
const visibleTop = Math.max(cellTop, verticalStart);
|
|
3550
|
+
const visibleBottom = Math.min(cellTop + cellHeight, renderHeight);
|
|
3005
3551
|
return {
|
|
3006
|
-
left:
|
|
3007
|
-
top:
|
|
3008
|
-
width:
|
|
3009
|
-
height:
|
|
3552
|
+
left: visibleLeft,
|
|
3553
|
+
top: visibleTop,
|
|
3554
|
+
width: Math.max(0, visibleRight - visibleLeft),
|
|
3555
|
+
height: Math.max(0, visibleBottom - visibleTop)
|
|
3010
3556
|
};
|
|
3011
|
-
}, [bodyTop, columns, editing, fixedHeader, fixedWidth, getCellDisplayWidth, getCellSpan, getScrollableColumnLeft, leftFixedOffsets, metrics, rightFixedOffsets, rowHeight, viewport.width]);
|
|
3557
|
+
}, [bodyTop, columns, editing, fixedHeader, fixedWidth, getCellDisplayWidth, getCellSpan, getScrollableColumnLeft, leftFixedOffsets, metrics, renderHeight, rightFixedOffsets, rightFixedWidth, rowHeight, viewport.width]);
|
|
3012
3558
|
const handleColumnPointerDown = (0, import_react5.useCallback)((event) => {
|
|
3013
3559
|
const rect = event.currentTarget.getBoundingClientRect();
|
|
3014
3560
|
const localY = event.clientY - rect.top;
|
|
@@ -3028,9 +3574,10 @@ function Table({
|
|
|
3028
3574
|
columnIndex: resizeIndex,
|
|
3029
3575
|
startX: event.clientX,
|
|
3030
3576
|
startWidth: startWidths.reduce((total, width2) => total + width2, 0),
|
|
3031
|
-
startGuideX,
|
|
3032
3577
|
guideTop: headerRowOffsets[resizeCell.level] ?? 0,
|
|
3033
3578
|
resizeEdge,
|
|
3579
|
+
resizeStartIndex: resizeCell.startIndex,
|
|
3580
|
+
resizeEndIndex: resizeCell.endIndex,
|
|
3034
3581
|
resizeIndices,
|
|
3035
3582
|
startWidths
|
|
3036
3583
|
};
|
|
@@ -3047,6 +3594,12 @@ function Table({
|
|
|
3047
3594
|
const minWidth = getMinimumColumnWidth(column, columnDraggable);
|
|
3048
3595
|
const pointerDelta = Math.round(event.clientX - drag.startX);
|
|
3049
3596
|
const delta = drag.resizeEdge === "left" ? -pointerDelta : pointerDelta;
|
|
3597
|
+
const setGuideFromWidths = (nextWidths) => {
|
|
3598
|
+
const widthByIndex = new Map(drag.resizeIndices.map((columnIndex, index) => [columnIndex, nextWidths[index]]));
|
|
3599
|
+
const nextColumns = columns.map((column2, index) => widthByIndex.has(index) ? { ...column2, width: widthByIndex.get(index) } : column2);
|
|
3600
|
+
const nextMetrics = buildColumnMetrics(nextColumns, { columnDraggable, viewportWidth: viewport.width });
|
|
3601
|
+
setResizeGuideX(getHeaderCellEdgeFromMetrics(drag.resizeStartIndex, drag.resizeEndIndex, drag.resizeEdge, nextMetrics));
|
|
3602
|
+
};
|
|
3050
3603
|
if (drag.resizeIndices.length > 1) {
|
|
3051
3604
|
const minWidths = drag.resizeIndices.map((index) => getMinimumColumnWidth(columns[index], columnDraggable));
|
|
3052
3605
|
const minTotalWidth = minWidths.reduce((total, width3) => total + width3, 0);
|
|
@@ -3063,13 +3616,13 @@ function Table({
|
|
|
3063
3616
|
drag.resizeIndices.forEach((columnIndex, index) => {
|
|
3064
3617
|
resizeColumn(columns[columnIndex].key, nextWidths[index]);
|
|
3065
3618
|
});
|
|
3066
|
-
|
|
3619
|
+
setGuideFromWidths(nextWidths);
|
|
3067
3620
|
return;
|
|
3068
3621
|
}
|
|
3069
3622
|
const width2 = Math.max(minWidth, Math.round(drag.startWidth + delta));
|
|
3070
3623
|
resizeColumn(column.key, width2);
|
|
3071
|
-
|
|
3072
|
-
}, [columnDraggable, columns, resizeColumn]);
|
|
3624
|
+
setGuideFromWidths([width2]);
|
|
3625
|
+
}, [columnDraggable, columns, getHeaderCellEdgeFromMetrics, resizeColumn, viewport.width]);
|
|
3073
3626
|
const handleColumnPointerUp = (0, import_react5.useCallback)((event) => {
|
|
3074
3627
|
const drag = columnDragRef.current;
|
|
3075
3628
|
if (!drag) return;
|
|
@@ -3079,19 +3632,14 @@ function Table({
|
|
|
3079
3632
|
setResizeGuideTop(0);
|
|
3080
3633
|
}, []);
|
|
3081
3634
|
const queueSortStateChange = (0, import_react5.useCallback)((next) => {
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
sortDebounceRef.current = setTimeout(() => {
|
|
3085
|
-
sortDebounceRef.current = null;
|
|
3086
|
-
onSortStateChange?.(next);
|
|
3087
|
-
}, 200);
|
|
3088
|
-
}, [onSortStateChange]);
|
|
3635
|
+
setSortState(next);
|
|
3636
|
+
}, []);
|
|
3089
3637
|
const renderHeaderIcons = (columnIndex, left) => {
|
|
3090
3638
|
const column = columns[columnIndex];
|
|
3091
3639
|
if (column.rowSelection || column.rowDragHandle || column.rowNumber) return null;
|
|
3092
3640
|
const top = headerLeafTop + (headerLeafHeight - 14) / 2;
|
|
3093
3641
|
const visibleActions = getVisibleHeaderActions(column, metrics[columnIndex].width, columnDraggable, measureHeaderTitleWidth(columnIndex));
|
|
3094
|
-
let right = left + metrics[columnIndex].width - (visibleActions.drag ?
|
|
3642
|
+
let right = left + metrics[columnIndex].width - (visibleActions.drag ? HEADER_ACTION_SLOT_WIDTH : 2);
|
|
3095
3643
|
const icons = [];
|
|
3096
3644
|
if (visibleActions.drag) {
|
|
3097
3645
|
const hovered = hoveredHeaderAction?.columnIndex === columnIndex && hoveredHeaderAction.action === "drag";
|
|
@@ -3101,11 +3649,11 @@ function Table({
|
|
|
3101
3649
|
}
|
|
3102
3650
|
if (visibleActions.sort) {
|
|
3103
3651
|
const hovered = hoveredHeaderAction?.columnIndex === columnIndex && hoveredHeaderAction.action === "sort";
|
|
3104
|
-
const direction =
|
|
3652
|
+
const direction = sortState?.columnKey === column.key ? sortState.direction : null;
|
|
3105
3653
|
icons.push(
|
|
3106
3654
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(HeaderSortIcon, { className: `rvg-header-icon${hovered ? " is-hovered" : ""}`, style: { left: right - 16, top }, direction }, "sort")
|
|
3107
3655
|
);
|
|
3108
|
-
right -=
|
|
3656
|
+
right -= HEADER_ACTION_SLOT_WIDTH;
|
|
3109
3657
|
}
|
|
3110
3658
|
if (visibleActions.filter) {
|
|
3111
3659
|
const hovered = hoveredHeaderAction?.columnIndex === columnIndex && hoveredHeaderAction.action === "filter";
|
|
@@ -3132,7 +3680,7 @@ function Table({
|
|
|
3132
3680
|
if (context) context.font = "600 13px Inter, ui-sans-serif, system-ui, sans-serif";
|
|
3133
3681
|
const titleWidth = context?.measureText(column.title).width ?? column.title.length * 13;
|
|
3134
3682
|
const visibleActions = cell?.leaf || !cell ? getVisibleHeaderActions(column, cellWidth, columnDraggable, titleWidth) : null;
|
|
3135
|
-
const actionWidth = visibleActions ? (Number(visibleActions.drag) + Number(visibleActions.filter) + Number(visibleActions.sort)) *
|
|
3683
|
+
const actionWidth = visibleActions ? (Number(visibleActions.drag) + Number(visibleActions.filter) + Number(visibleActions.sort)) * HEADER_ACTION_SLOT_WIDTH : columnDraggable ? HEADER_ACTION_SLOT_WIDTH : 0;
|
|
3136
3684
|
const contentWidth2 = Math.max(0, cellWidth - actionWidth);
|
|
3137
3685
|
const maxTextWidth = Math.max(0, contentWidth2 - 20);
|
|
3138
3686
|
const textWidth = Math.min(titleWidth, maxTextWidth);
|
|
@@ -3151,7 +3699,7 @@ function Table({
|
|
|
3151
3699
|
anchorLeft = anchorX;
|
|
3152
3700
|
label = labels.dragColumn;
|
|
3153
3701
|
} else if (action === "sort") {
|
|
3154
|
-
const direction =
|
|
3702
|
+
const direction = sortState?.columnKey === column.key ? sortState.direction : null;
|
|
3155
3703
|
label = direction === "asc" ? labels.sortAsc : direction === "desc" ? labels.sortDesc : labels.sortBoth;
|
|
3156
3704
|
anchorX = cellLeft + cellWidth - 22;
|
|
3157
3705
|
anchorLeft = anchorX;
|
|
@@ -3171,7 +3719,7 @@ function Table({
|
|
|
3171
3719
|
label,
|
|
3172
3720
|
placement
|
|
3173
3721
|
};
|
|
3174
|
-
}, [baseHeaderHeight, columnDraggable, columns,
|
|
3722
|
+
}, [baseHeaderHeight, columnDraggable, columns, filterValues, fixedHeader, getDisplayedColumnLeft, getHeaderCellLeft, getHeaderCellWidth, headerDepth, headerRowHeights, headerRowOffsets, labels, metrics, scrollPosition.top, sortState, viewport.width]);
|
|
3175
3723
|
const isPointerOnHeaderTitle = (0, import_react5.useCallback)((clientX, clientY, cell) => {
|
|
3176
3724
|
const canvas = canvasRef.current;
|
|
3177
3725
|
if (!canvas) return false;
|
|
@@ -3186,7 +3734,7 @@ function Table({
|
|
|
3186
3734
|
if (context) context.font = "600 13px Inter, ui-sans-serif, system-ui, sans-serif";
|
|
3187
3735
|
const titleWidth = context?.measureText(column.title).width ?? column.title.length * 13;
|
|
3188
3736
|
const visibleActions = cell.leaf ? getVisibleHeaderActions(column, cellWidth, columnDraggable, titleWidth) : null;
|
|
3189
|
-
const actionWidth = visibleActions ? (Number(visibleActions.drag) + Number(visibleActions.filter) + Number(visibleActions.sort)) *
|
|
3737
|
+
const actionWidth = visibleActions ? (Number(visibleActions.drag) + Number(visibleActions.filter) + Number(visibleActions.sort)) * HEADER_ACTION_SLOT_WIDTH : columnDraggable ? HEADER_ACTION_SLOT_WIDTH : 0;
|
|
3190
3738
|
const contentWidth2 = Math.max(0, cellWidth - actionWidth);
|
|
3191
3739
|
const textWidth = Math.min(titleWidth, Math.max(0, contentWidth2 - 20));
|
|
3192
3740
|
const textLeft = column.align === "right" ? cellLeft + contentWidth2 - 10 - textWidth : column.align === "center" ? cellLeft + contentWidth2 / 2 - textWidth / 2 : cellLeft + 10;
|
|
@@ -3426,7 +3974,9 @@ function Table({
|
|
|
3426
3974
|
});
|
|
3427
3975
|
setPendingInserts((current) => [...current, pending]);
|
|
3428
3976
|
try {
|
|
3429
|
-
|
|
3977
|
+
const nextRows = sourceRows.slice();
|
|
3978
|
+
nextRows.splice(insertIndex, 0, ...insertedRows);
|
|
3979
|
+
await Promise.resolve(onInsertRows(nextRows, insertedRows));
|
|
3430
3980
|
await waitForPaint();
|
|
3431
3981
|
setInsertBusy(false);
|
|
3432
3982
|
} catch (error) {
|
|
@@ -3453,28 +4003,10 @@ function Table({
|
|
|
3453
4003
|
const currentScrollTop = scrollRef.current.top;
|
|
3454
4004
|
const top = (fixedHeader ? 0 : bodyTop) + rowIndex * rowHeight - currentScrollTop;
|
|
3455
4005
|
if (column.rowSelection) {
|
|
3456
|
-
|
|
3457
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3458
|
-
"div",
|
|
3459
|
-
{
|
|
3460
|
-
className: "rvg-row-selection-icon",
|
|
3461
|
-
style: { left, top, width: cellWidth, height: cellHeight, opacity: isDraggedSource ? 0 : 1, transform: `translateY(${dragOffset}px)` },
|
|
3462
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SelectionIcon, { checked: selectedRowKeySet.has(rowKey2), radio: rowSelectionMode === "single" })
|
|
3463
|
-
},
|
|
3464
|
-
`selection:${String(rowKey2)}`
|
|
3465
|
-
);
|
|
4006
|
+
return null;
|
|
3466
4007
|
}
|
|
3467
4008
|
if (column.rowDragHandle) {
|
|
3468
|
-
return
|
|
3469
|
-
"div",
|
|
3470
|
-
{
|
|
3471
|
-
className: "rvg-row-drag-icon",
|
|
3472
|
-
style: { left, top, width: cellWidth, height: cellHeight, opacity: isDraggedSource ? 0 : 1, transform: `translateY(${dragOffset}px)` },
|
|
3473
|
-
"aria-hidden": "true",
|
|
3474
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(RowDragHandleIcon, {})
|
|
3475
|
-
},
|
|
3476
|
-
`drag:${String(getRowKey(rows[rowIndex], rowIndex))}`
|
|
3477
|
-
);
|
|
4009
|
+
return null;
|
|
3478
4010
|
}
|
|
3479
4011
|
if (column.renderCell && !(editing?.rowIndex === rowIndex && editing.columnIndex === columnIndex)) {
|
|
3480
4012
|
const row = rows[rowIndex];
|
|
@@ -3501,6 +4033,7 @@ function Table({
|
|
|
3501
4033
|
};
|
|
3502
4034
|
const renderHeaderTitle = (columnIndex, left) => {
|
|
3503
4035
|
const column = columns[columnIndex];
|
|
4036
|
+
const isDropTarget = Boolean(columnDropTarget && columnIndex >= columnDropTarget.startIndex && columnIndex <= columnDropTarget.endIndex);
|
|
3504
4037
|
const currentScrollTop = scrollRef.current.top;
|
|
3505
4038
|
const headerTop = fixedHeader ? 0 : -currentScrollTop;
|
|
3506
4039
|
const leafTop = headerTop + headerLeafTop;
|
|
@@ -3508,7 +4041,7 @@ function Table({
|
|
|
3508
4041
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3509
4042
|
"div",
|
|
3510
4043
|
{
|
|
3511
|
-
className:
|
|
4044
|
+
className: `rvg-header-title${isDropTarget ? " is-drop-target" : ""}`,
|
|
3512
4045
|
style: { left, top: headerTop, width: metrics[columnIndex].width, height: headerHeight, justifyContent: "center", padding: 0, textAlign: "center" },
|
|
3513
4046
|
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: column.title })
|
|
3514
4047
|
},
|
|
@@ -3531,11 +4064,11 @@ function Table({
|
|
|
3531
4064
|
}
|
|
3532
4065
|
if (column.renderHeader) {
|
|
3533
4066
|
const visibleActions = getVisibleHeaderActions(column, metrics[columnIndex].width, columnDraggable, measureHeaderTitleWidth(columnIndex));
|
|
3534
|
-
const actionWidth = (Number(visibleActions.drag) + Number(visibleActions.filter) + Number(visibleActions.sort)) *
|
|
4067
|
+
const actionWidth = (Number(visibleActions.drag) + Number(visibleActions.filter) + Number(visibleActions.sort)) * HEADER_ACTION_SLOT_WIDTH;
|
|
3535
4068
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
3536
4069
|
"div",
|
|
3537
4070
|
{
|
|
3538
|
-
className:
|
|
4071
|
+
className: `rvg-header-title is-custom${isDropTarget ? " is-drop-target" : ""}`,
|
|
3539
4072
|
"data-level": headerDepth - 1,
|
|
3540
4073
|
"data-measure-key": column.key,
|
|
3541
4074
|
style: {
|
|
@@ -3576,11 +4109,12 @@ function Table({
|
|
|
3576
4109
|
const left = fixedSide === "left" ? leftFixedOffsets.get(cell.startIndex) ?? 0 : fixedSide === "right" ? viewport.width - (rightFixedOffsets.get(cell.startIndex) ?? 0) - startMetric.width : getScrollableColumnLeft(cell.startIndex);
|
|
3577
4110
|
const width2 = cell.leaf ? startMetric.width : getCellDisplayWidth(cell.startIndex, cell.endIndex - cell.startIndex + 1);
|
|
3578
4111
|
const visibleActions = cell.leaf ? getVisibleHeaderActions(column, startMetric.width, columnDraggable, measureHeaderTitleWidth(cell.startIndex)) : null;
|
|
3579
|
-
const actionWidth = visibleActions ? (Number(visibleActions.drag) + Number(visibleActions.filter) + Number(visibleActions.sort)) *
|
|
4112
|
+
const actionWidth = visibleActions ? (Number(visibleActions.drag) + Number(visibleActions.filter) + Number(visibleActions.sort)) * HEADER_ACTION_SLOT_WIDTH : columnDraggable && !cell.leaf ? HEADER_ACTION_SLOT_WIDTH : 0;
|
|
4113
|
+
const isDropTarget = Boolean(columnDropTarget && cell.endIndex >= columnDropTarget.startIndex && cell.startIndex <= columnDropTarget.endIndex);
|
|
3580
4114
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
3581
4115
|
"div",
|
|
3582
4116
|
{
|
|
3583
|
-
className: `rvg-header-title rvg-header-group${column.renderHeader ? " is-custom" : ""}${cell.leaf ? " is-leaf" : ""}`,
|
|
4117
|
+
className: `rvg-header-title rvg-header-group${column.renderHeader ? " is-custom" : ""}${cell.leaf ? " is-leaf" : ""}${isDropTarget ? " is-drop-target" : ""}`,
|
|
3584
4118
|
"data-level": cell.level,
|
|
3585
4119
|
"data-measure-key": `group:${cell.key}:${cell.level}`,
|
|
3586
4120
|
style: {
|
|
@@ -3636,6 +4170,7 @@ function Table({
|
|
|
3636
4170
|
})();
|
|
3637
4171
|
const selectionOutlineStyle = (() => {
|
|
3638
4172
|
if (!selection || selectionRange) return null;
|
|
4173
|
+
if (rowDragPreview?.sourceIndex === selection.rowIndex) return null;
|
|
3639
4174
|
const row = rows[selection.rowIndex];
|
|
3640
4175
|
const metric = metrics[selection.columnIndex];
|
|
3641
4176
|
const column = columns[selection.columnIndex];
|
|
@@ -3645,22 +4180,37 @@ function Table({
|
|
|
3645
4180
|
const rawRight = rawLeft + getCellDisplayWidth(selection.columnIndex, span?.colSpan ?? 1);
|
|
3646
4181
|
const rawTop = bodyTop + selection.rowIndex * rowHeight - scrollPosition.top;
|
|
3647
4182
|
const rawBottom = rawTop + rowHeight * (span?.rowSpan ?? 1);
|
|
4183
|
+
const dragOffset = getRowDragOffset(selection.rowIndex);
|
|
3648
4184
|
const horizontalStart = column.fixed === void 0 ? fixedWidth : 0;
|
|
3649
4185
|
const horizontalEnd = column.fixed === void 0 ? viewport.width - rightFixedWidth : viewport.width;
|
|
3650
4186
|
const verticalStart = fixedHeader ? bodyTop : 0;
|
|
3651
|
-
if (rawRight <= horizontalStart || rawLeft >= horizontalEnd || rawBottom <= verticalStart || rawTop >= renderHeight) return null;
|
|
4187
|
+
if (rawRight <= horizontalStart || rawLeft >= horizontalEnd || rawBottom + dragOffset <= verticalStart || rawTop + dragOffset >= renderHeight) return null;
|
|
3652
4188
|
const borderWidth = 2;
|
|
3653
|
-
const left = Math.round(Math.max(rawLeft - borderWidth, horizontalStart
|
|
4189
|
+
const left = Math.round(Math.max(rawLeft - borderWidth, horizontalStart));
|
|
3654
4190
|
const right = Math.round(Math.min(rawRight + 1, horizontalEnd, viewport.width));
|
|
3655
|
-
const top = Math.round(Math.max(rawTop - borderWidth, verticalStart
|
|
4191
|
+
const top = Math.round(Math.max(rawTop - borderWidth, verticalStart));
|
|
3656
4192
|
const bottom = Math.round(Math.min(rawBottom + 1, renderHeight));
|
|
3657
4193
|
return {
|
|
3658
4194
|
left,
|
|
3659
4195
|
top,
|
|
3660
4196
|
width: Math.max(0, right - left),
|
|
3661
|
-
height: Math.max(0, bottom - top)
|
|
4197
|
+
height: Math.max(0, bottom - top),
|
|
4198
|
+
transform: `translateY(${dragOffset}px)`
|
|
3662
4199
|
};
|
|
3663
4200
|
})();
|
|
4201
|
+
const selectionEdgeIndicator = getSelectionEdgeIndicator(scrollPosition.left, scrollPosition.top);
|
|
4202
|
+
const selectionEdgeStyle = selectionEdgeIndicator ? {
|
|
4203
|
+
...selectionEdgeIndicator.style,
|
|
4204
|
+
...selectionEdgeIndicator.corner ? {
|
|
4205
|
+
"--rvg-corner-width": `${selectionEdgeIndicator.corner.width}px`,
|
|
4206
|
+
"--rvg-corner-height": `${selectionEdgeIndicator.corner.height}px`,
|
|
4207
|
+
"--rvg-corner-hover-width-extension": "4px",
|
|
4208
|
+
"--rvg-corner-hover-height-extension": "4px"
|
|
4209
|
+
} : null
|
|
4210
|
+
} : void 0;
|
|
4211
|
+
(0, import_react5.useLayoutEffect)(() => {
|
|
4212
|
+
syncSelectionEdgeTarget(scrollPosition.left, scrollPosition.top);
|
|
4213
|
+
}, [scrollPosition.left, scrollPosition.top, syncSelectionEdgeTarget]);
|
|
3664
4214
|
const handleContextMenu = (event) => {
|
|
3665
4215
|
event.preventDefault();
|
|
3666
4216
|
event.stopPropagation();
|
|
@@ -3804,6 +4354,10 @@ function Table({
|
|
|
3804
4354
|
className: "rvg-canvas",
|
|
3805
4355
|
style: { width: viewport.width, height: renderHeight },
|
|
3806
4356
|
onMouseMove: (event) => {
|
|
4357
|
+
if (document.documentElement.classList.contains("rvg-is-dragging")) {
|
|
4358
|
+
hideDragTooltips();
|
|
4359
|
+
return;
|
|
4360
|
+
}
|
|
3807
4361
|
if (columnDragRef.current) return;
|
|
3808
4362
|
const rect = event.currentTarget.getBoundingClientRect();
|
|
3809
4363
|
const localY = event.clientY - rect.top;
|
|
@@ -3906,6 +4460,14 @@ function Table({
|
|
|
3906
4460
|
}
|
|
3907
4461
|
},
|
|
3908
4462
|
onPointerDown: (event) => {
|
|
4463
|
+
const headerDragCell = columnDraggable ? locateHeaderCell(event.clientX, event.clientY) : null;
|
|
4464
|
+
const columnIndex = locateColumn(event.clientX);
|
|
4465
|
+
const rowDragHandle = rowDraggable && columnIndex >= 0 && Boolean(columns[columnIndex].rowDragHandle) && locateRow(event.clientY) >= 0;
|
|
4466
|
+
if (headerDragCell && locateHeaderCellDragHandle(event.clientX, headerDragCell) || rowDragHandle) {
|
|
4467
|
+
hideDragTooltips();
|
|
4468
|
+
document.documentElement.classList.add("rvg-is-dragging");
|
|
4469
|
+
event.currentTarget.style.cursor = "move";
|
|
4470
|
+
}
|
|
3909
4471
|
handleColumnPointerDown(event);
|
|
3910
4472
|
beginRangeDrag(event);
|
|
3911
4473
|
},
|
|
@@ -3914,10 +4476,12 @@ function Table({
|
|
|
3914
4476
|
updateRangeDrag(event);
|
|
3915
4477
|
},
|
|
3916
4478
|
onPointerUp: (event) => {
|
|
4479
|
+
document.documentElement.classList.remove("rvg-is-dragging");
|
|
3917
4480
|
handleColumnPointerUp(event);
|
|
3918
4481
|
endRangeDrag(event);
|
|
3919
4482
|
},
|
|
3920
4483
|
onPointerCancel: (event) => {
|
|
4484
|
+
document.documentElement.classList.remove("rvg-is-dragging");
|
|
3921
4485
|
handleColumnPointerUp(event);
|
|
3922
4486
|
endRangeDrag(event);
|
|
3923
4487
|
},
|
|
@@ -3936,7 +4500,7 @@ function Table({
|
|
|
3936
4500
|
const action = locateHeaderAction(event.clientX, columnIndex);
|
|
3937
4501
|
if (action === "sort") {
|
|
3938
4502
|
const columnKey = columns[columnIndex].key;
|
|
3939
|
-
const next =
|
|
4503
|
+
const next = sortState?.columnKey !== columnKey ? { columnKey, direction: "asc" } : sortState.direction === "asc" ? { columnKey, direction: "desc" } : null;
|
|
3940
4504
|
queueSortStateChange(next);
|
|
3941
4505
|
return;
|
|
3942
4506
|
}
|
|
@@ -4108,6 +4672,27 @@ function Table({
|
|
|
4108
4672
|
}
|
|
4109
4673
|
),
|
|
4110
4674
|
selectionOutlineStyle && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { ref: selectionFocusRef, className: "rvg-selection-focus", style: selectionOutlineStyle, "aria-hidden": "true" }),
|
|
4675
|
+
selectionEdgeIndicator && selection && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4676
|
+
"button",
|
|
4677
|
+
{
|
|
4678
|
+
ref: selectionEdgeTargetRef,
|
|
4679
|
+
type: "button",
|
|
4680
|
+
className: `rvg-selection-edge-target is-${selectionEdgeIndicator.orientation} is-${selectionEdgeIndicator.side}${selectionEdgeIndicator.viewportEdge ? ` is-viewport-${selectionEdgeIndicator.viewportEdge}` : ""}`,
|
|
4681
|
+
style: selectionEdgeStyle,
|
|
4682
|
+
"aria-label": labels.revealSelectedCell,
|
|
4683
|
+
title: labels.revealSelectedCell,
|
|
4684
|
+
onPointerDown: (event) => {
|
|
4685
|
+
event.preventDefault();
|
|
4686
|
+
event.stopPropagation();
|
|
4687
|
+
},
|
|
4688
|
+
onClick: (event) => {
|
|
4689
|
+
event.stopPropagation();
|
|
4690
|
+
scrollerRef.current?.focus({ preventScroll: true });
|
|
4691
|
+
revealCell(selection);
|
|
4692
|
+
},
|
|
4693
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "rvg-selection-edge-halo", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { viewBox: "0 0 100 100", preserveAspectRatio: "none", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M 0 100 L 0 0 L 100 0" }) }) })
|
|
4694
|
+
}
|
|
4695
|
+
),
|
|
4111
4696
|
contextMenu && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { ref: contextMenuRef, className: "rvg-context-menu", role: "menu", style: { left: contextMenu.left, top: contextMenu.top }, children: contextMenu.type === "header" ? (() => {
|
|
4112
4697
|
const column = columns[contextMenu.columnIndex];
|
|
4113
4698
|
const headerContext = { column, columnIndex: contextMenu.columnIndex };
|
|
@@ -4265,12 +4850,12 @@ function Table({
|
|
|
4265
4850
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: labels.rowUnit })
|
|
4266
4851
|
] });
|
|
4267
4852
|
if (item === "move-up") {
|
|
4268
|
-
if (!rowDraggable
|
|
4269
|
-
return renderContextMenuButton("cell-move-up", cellContext, labels.moveUp, () =>
|
|
4853
|
+
if (!rowDraggable) return null;
|
|
4854
|
+
return renderContextMenuButton("cell-move-up", cellContext, labels.moveUp, () => applyRowOrder(cell.rowIndex, cell.rowIndex - 1), override, { disabled: cell.rowIndex === 0, icon: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ContextMenuIcon, { type: "move-up" }) });
|
|
4270
4855
|
}
|
|
4271
4856
|
if (item === "move-down") {
|
|
4272
|
-
if (!rowDraggable
|
|
4273
|
-
return renderContextMenuButton("cell-move-down", cellContext, labels.moveDown, () =>
|
|
4857
|
+
if (!rowDraggable) return null;
|
|
4858
|
+
return renderContextMenuButton("cell-move-down", cellContext, labels.moveDown, () => applyRowOrder(cell.rowIndex, cell.rowIndex + 1), override, { disabled: cell.rowIndex === rows.length - 1, icon: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ContextMenuIcon, { type: "move-down" }) });
|
|
4274
4859
|
}
|
|
4275
4860
|
if (item === "delete-row") return renderContextMenuButton("cell-delete-row", cellContext, labels.deleteRow, () => setConfirmAction({ type: "delete-row", rows: affectedRows.map((rowIndex) => ({ rowIndex, row: rows[rowIndex] })) }), override, { disabled: !onDeleteRows, danger: true, icon: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ContextMenuIcon, { type: "delete" }) });
|
|
4276
4861
|
return null;
|
|
@@ -4302,21 +4887,30 @@ function Table({
|
|
|
4302
4887
|
await Promise.resolve(onCellChange?.({ ...confirmAction.cell, row: confirmAction.row, previousValue: confirmAction.previousValue, value: "" }));
|
|
4303
4888
|
} else {
|
|
4304
4889
|
const deletingKeys = confirmAction.rows.map(({ row, rowIndex }) => getDataRowKey(row, rowIndex));
|
|
4890
|
+
const deletedRows = confirmAction.rows.map(({ row }) => row);
|
|
4891
|
+
const deletingKeySet = new Set(deletingKeys);
|
|
4892
|
+
const nextRows = sourceRows.filter((row, rowIndex) => !deletingKeySet.has(getDataRowKey(row, rowIndex)));
|
|
4305
4893
|
setConfirmAction(null);
|
|
4306
4894
|
setConfirmLoading(false);
|
|
4895
|
+
setPendingDeletedRowKeys((current) => {
|
|
4896
|
+
const next = new Set(current);
|
|
4897
|
+
deletingKeys.forEach((key) => next.add(key));
|
|
4898
|
+
return next;
|
|
4899
|
+
});
|
|
4307
4900
|
if (onDeleteRows) {
|
|
4308
4901
|
setDeleteBusy(true);
|
|
4309
4902
|
try {
|
|
4310
|
-
await Promise.resolve(onDeleteRows(
|
|
4903
|
+
await Promise.resolve(onDeleteRows(nextRows, deletedRows));
|
|
4904
|
+
} catch (error) {
|
|
4905
|
+
setPendingDeletedRowKeys((current) => {
|
|
4906
|
+
const next = new Set(current);
|
|
4907
|
+
deletingKeys.forEach((key) => next.delete(key));
|
|
4908
|
+
return next;
|
|
4909
|
+
});
|
|
4910
|
+
throw error;
|
|
4311
4911
|
} finally {
|
|
4312
4912
|
setDeleteBusy(false);
|
|
4313
4913
|
}
|
|
4314
|
-
} else {
|
|
4315
|
-
setPendingDeletedRowKeys((current) => {
|
|
4316
|
-
const next = new Set(current);
|
|
4317
|
-
deletingKeys.forEach((key) => next.add(key));
|
|
4318
|
-
return next;
|
|
4319
|
-
});
|
|
4320
4914
|
}
|
|
4321
4915
|
return;
|
|
4322
4916
|
}
|
|
@@ -4389,7 +4983,7 @@ function Table({
|
|
|
4389
4983
|
const next = { ...filterValues };
|
|
4390
4984
|
if (filterEditor.draft) next[key] = filterEditor.draft;
|
|
4391
4985
|
else delete next[key];
|
|
4392
|
-
|
|
4986
|
+
setFilterValues(next);
|
|
4393
4987
|
setFilterEditor(null);
|
|
4394
4988
|
}
|
|
4395
4989
|
}
|
|
@@ -4400,7 +4994,7 @@ function Table({
|
|
|
4400
4994
|
const key = columns[filterEditor.columnIndex].key;
|
|
4401
4995
|
const next = { ...filterValues };
|
|
4402
4996
|
delete next[key];
|
|
4403
|
-
|
|
4997
|
+
setFilterValues(next);
|
|
4404
4998
|
setFilterEditor(null);
|
|
4405
4999
|
}, children: labels.reset }),
|
|
4406
5000
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: "rvg-filter-confirm", onClick: () => {
|
|
@@ -4408,7 +5002,7 @@ function Table({
|
|
|
4408
5002
|
const next = { ...filterValues };
|
|
4409
5003
|
if (filterEditor.draft) next[key] = filterEditor.draft;
|
|
4410
5004
|
else delete next[key];
|
|
4411
|
-
|
|
5005
|
+
setFilterValues(next);
|
|
4412
5006
|
setFilterEditor(null);
|
|
4413
5007
|
}, children: labels.confirm })
|
|
4414
5008
|
] })
|
|
@@ -4432,8 +5026,8 @@ function Table({
|
|
|
4432
5026
|
column.key
|
|
4433
5027
|
);
|
|
4434
5028
|
}) }, rowIndex)),
|
|
4435
|
-
fixedWidth > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "rvg-loading-fixed-shadow is-left", style: { left: fixedWidth } }),
|
|
4436
|
-
rightFixedWidth > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "rvg-loading-fixed-shadow is-right", style: { right: rightFixedWidth } })
|
|
5029
|
+
fixedWidth > 0 && currentScroll.left > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "rvg-loading-fixed-shadow is-left", style: { left: fixedWidth } }),
|
|
5030
|
+
rightFixedWidth > 0 && currentScroll.left < contentWidth - viewport.width && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "rvg-loading-fixed-shadow is-right", style: { right: rightFixedWidth } })
|
|
4437
5031
|
] }),
|
|
4438
5032
|
loading && !hasCustomLoading && hasCompletedLoadRef.current && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "rvg-refresh-loading", "aria-label": labels.refreshing, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(LoadingSpinnerIcon, {}) })
|
|
4439
5033
|
] });
|