@lensui/lens-table 0.1.4 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +313 -43
- package/dist/index.css +306 -3
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +313 -43
- 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",
|
|
@@ -333,7 +335,6 @@ function LoadingSpinnerIcon() {
|
|
|
333
335
|
// src/components/editors/ChoiceEditor.tsx
|
|
334
336
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
335
337
|
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
338
|
const collection = (0, import_select.createListCollection)({
|
|
338
339
|
items: options,
|
|
339
340
|
itemToValue: (item) => item.value,
|
|
@@ -343,7 +344,7 @@ function ChoiceEditor({ value, options, style, labels, onChange, onCommit, onCan
|
|
|
343
344
|
import_select.Select.Root,
|
|
344
345
|
{
|
|
345
346
|
className: "rvg-choice-editor",
|
|
346
|
-
style
|
|
347
|
+
style,
|
|
347
348
|
collection,
|
|
348
349
|
value: value ? [value] : [],
|
|
349
350
|
defaultOpen: true,
|
|
@@ -914,6 +915,7 @@ function paintGrid(options) {
|
|
|
914
915
|
const leftFixedWidth = columns.reduce((value, column, index) => column.fixed === "left" ? value + metrics[index].width : value, 0);
|
|
915
916
|
const rightFixedWidth = columns.reduce((value, column, index) => column.fixed === "right" ? value + metrics[index].width : value, 0);
|
|
916
917
|
const rightFixedLeft = width - rightFixedWidth;
|
|
918
|
+
const rightFixedBoundaryInset = rightFixedWidth > 0 && !verticalBorderless ? 1 : 0;
|
|
917
919
|
const leftOffsets = /* @__PURE__ */ new Map();
|
|
918
920
|
let leftOffset = 0;
|
|
919
921
|
for (let index = 0; index < columns.length; index += 1) {
|
|
@@ -1137,22 +1139,22 @@ function paintGrid(options) {
|
|
|
1137
1139
|
const markerBottom = Math.min(bottom, height);
|
|
1138
1140
|
const startX = getColumnX(columnStart);
|
|
1139
1141
|
const endX = getColumnX(columnEnd) + metrics[columnEnd].width;
|
|
1140
|
-
const visibleLeft = columns[columnStart].fixed === "left" ? Math.max(0, startX) : Math.max(leftFixedWidth
|
|
1142
|
+
const visibleLeft = columns[columnStart].fixed === "left" ? Math.max(0, startX) : Math.max(leftFixedWidth, startX);
|
|
1141
1143
|
const visibleRight = columns[columnEnd].fixed === "right" ? Math.min(width, endX) : Math.min(rightFixedLeft, endX);
|
|
1142
1144
|
ctx.fillStyle = colors.selection;
|
|
1143
1145
|
if (markerBottom > markerTop) {
|
|
1144
1146
|
if (columns[columnStart].fixed === void 0 && startX < leftFixedWidth) {
|
|
1145
|
-
ctx.fillRect(Math.max(0, leftFixedWidth
|
|
1147
|
+
ctx.fillRect(Math.max(0, leftFixedWidth), markerTop, 2, markerBottom - markerTop);
|
|
1146
1148
|
}
|
|
1147
1149
|
if (columns[columnEnd].fixed === void 0 && endX > rightFixedLeft) {
|
|
1148
|
-
ctx.fillRect(Math.max(0, rightFixedLeft -
|
|
1150
|
+
ctx.fillRect(Math.max(0, rightFixedLeft - 2 - rightFixedBoundaryInset), markerTop, 2, markerBottom - markerTop);
|
|
1149
1151
|
}
|
|
1150
1152
|
}
|
|
1151
1153
|
if (visibleRight > visibleLeft) {
|
|
1152
1154
|
if (top < clipTop) ctx.fillRect(visibleLeft, clipTop, visibleRight - visibleLeft, 2);
|
|
1153
1155
|
if (bottom > height) ctx.fillRect(visibleLeft, height - 2, visibleRight - visibleLeft, 2);
|
|
1154
1156
|
} else if (top < clipTop || bottom > height) {
|
|
1155
|
-
const markerX = endX <= leftFixedWidth ? Math.max(0, leftFixedWidth
|
|
1157
|
+
const markerX = endX <= leftFixedWidth ? Math.max(0, leftFixedWidth) : Math.max(0, rightFixedLeft - 2 - rightFixedBoundaryInset);
|
|
1156
1158
|
ctx.fillRect(markerX, top < clipTop ? clipTop : height - 2, 2, 2);
|
|
1157
1159
|
}
|
|
1158
1160
|
}
|
|
@@ -1174,15 +1176,15 @@ function paintGrid(options) {
|
|
|
1174
1176
|
const visibleRight = x + selectionWidth;
|
|
1175
1177
|
const visibleBottom = y + selectionHeight;
|
|
1176
1178
|
const selectionTop = fixedHeader ? bodyTop : 0;
|
|
1177
|
-
const selectionClipTop =
|
|
1179
|
+
const selectionClipTop = selectionTop;
|
|
1178
1180
|
const hiddenAboveHeader = visibleBottom <= selectionTop;
|
|
1179
1181
|
const hiddenBelowViewport = y >= height;
|
|
1180
1182
|
const hiddenBehindLeft = !isFixed && visibleRight <= visibleLeft;
|
|
1181
1183
|
const hiddenBehindRight = !isFixed && x >= selectionAreaRight;
|
|
1182
|
-
const leftMarkerX = Math.max(0, leftFixedWidth
|
|
1184
|
+
const leftMarkerX = Math.max(0, leftFixedWidth);
|
|
1183
1185
|
if ((hiddenAboveHeader || hiddenBelowViewport) && (hiddenBehindLeft || hiddenBehindRight)) {
|
|
1184
1186
|
const markerSize = 2;
|
|
1185
|
-
const markerX = hiddenBehindLeft ? leftMarkerX : selectionAreaRight - borderWidth;
|
|
1187
|
+
const markerX = hiddenBehindLeft ? leftMarkerX : selectionAreaRight - borderWidth - rightFixedBoundaryInset;
|
|
1186
1188
|
const markerY = hiddenAboveHeader ? selectionClipTop : height - markerSize;
|
|
1187
1189
|
ctx.fillStyle = colors.selection;
|
|
1188
1190
|
ctx.fillRect(markerX, markerY, markerSize, markerSize);
|
|
@@ -1190,7 +1192,7 @@ function paintGrid(options) {
|
|
|
1190
1192
|
}
|
|
1191
1193
|
ctx.save();
|
|
1192
1194
|
ctx.beginPath();
|
|
1193
|
-
const clipLeft = fixedSide === "left" ? 0 : Math.max(0, leftFixedWidth
|
|
1195
|
+
const clipLeft = fixedSide === "left" ? 0 : Math.max(0, leftFixedWidth);
|
|
1194
1196
|
const clipRight = Math.min(width, selectionAreaRight + 1);
|
|
1195
1197
|
ctx.rect(clipLeft, selectionClipTop, clipRight - clipLeft, height - selectionClipTop);
|
|
1196
1198
|
ctx.clip();
|
|
@@ -1208,14 +1210,14 @@ function paintGrid(options) {
|
|
|
1208
1210
|
if (hiddenBehindLeft || hiddenBehindRight) {
|
|
1209
1211
|
const markerTop = Math.max(y - borderWidth, selectionTop);
|
|
1210
1212
|
const markerBottom = Math.min(y + selectionHeight + 1, height);
|
|
1211
|
-
const markerX = hiddenBehindLeft ? leftMarkerX : selectionAreaRight - borderWidth;
|
|
1213
|
+
const markerX = hiddenBehindLeft ? leftMarkerX : selectionAreaRight - borderWidth - rightFixedBoundaryInset;
|
|
1212
1214
|
ctx.fillRect(markerX, markerTop, borderWidth, Math.max(0, markerBottom - markerTop));
|
|
1213
1215
|
}
|
|
1214
1216
|
if (hiddenAboveHeader || hiddenBelowViewport || hiddenBehindLeft || hiddenBehindRight) {
|
|
1215
1217
|
ctx.restore();
|
|
1216
1218
|
return;
|
|
1217
1219
|
}
|
|
1218
|
-
const borderLeft = x <= 0 ? 0 : Math.max(x - borderWidth, visibleLeft
|
|
1220
|
+
const borderLeft = x <= 0 ? 0 : Math.max(x - borderWidth, visibleLeft);
|
|
1219
1221
|
const borderRight = Math.min(x + selectionWidth - 1, selectionAreaRight - borderWidth, width - borderWidth);
|
|
1220
1222
|
const borderTop = Math.max(y - borderWidth, selectionClipTop);
|
|
1221
1223
|
const borderBottom = Math.min(y + selectionHeight - 1, height - borderWidth);
|
|
@@ -1324,6 +1326,25 @@ var createEmptyCellSpanLookup = () => ({
|
|
|
1324
1326
|
covered: /* @__PURE__ */ new Map(),
|
|
1325
1327
|
maxRowSpan: 1
|
|
1326
1328
|
});
|
|
1329
|
+
var summaryFunctionIds = /* @__PURE__ */ new WeakMap();
|
|
1330
|
+
var nextSummaryFunctionId = 1;
|
|
1331
|
+
function getSummaryFunctionId(fn) {
|
|
1332
|
+
if (!fn) return "";
|
|
1333
|
+
const existing = summaryFunctionIds.get(fn);
|
|
1334
|
+
if (existing !== void 0) return existing;
|
|
1335
|
+
const next = nextSummaryFunctionId;
|
|
1336
|
+
nextSummaryFunctionId += 1;
|
|
1337
|
+
summaryFunctionIds.set(fn, next);
|
|
1338
|
+
return next;
|
|
1339
|
+
}
|
|
1340
|
+
function getSummarySignature(columns) {
|
|
1341
|
+
return columns.filter((column) => Boolean(column.summary)).map((column) => [
|
|
1342
|
+
column.key,
|
|
1343
|
+
String(column.dataIndex ?? ""),
|
|
1344
|
+
typeof column.summary === "function" ? getSummaryFunctionId(column.summary) : "sum",
|
|
1345
|
+
getSummaryFunctionId(column.formatter)
|
|
1346
|
+
].join("")).join("");
|
|
1347
|
+
}
|
|
1327
1348
|
async function calculateSummaryValues(columns, rows) {
|
|
1328
1349
|
const values = /* @__PURE__ */ new Map();
|
|
1329
1350
|
for (const column of columns) {
|
|
@@ -1508,6 +1529,7 @@ function Table({
|
|
|
1508
1529
|
const dragGuideRef = (0, import_react5.useRef)(null);
|
|
1509
1530
|
const rowDragGuideRef = (0, import_react5.useRef)(null);
|
|
1510
1531
|
const selectionFocusRef = (0, import_react5.useRef)(null);
|
|
1532
|
+
const selectionEdgeTargetRef = (0, import_react5.useRef)(null);
|
|
1511
1533
|
const verticalScrollbarRef = (0, import_react5.useRef)(null);
|
|
1512
1534
|
const verticalScrollbarThumbRef = (0, import_react5.useRef)(null);
|
|
1513
1535
|
const verticalScrollbarDragRef = (0, import_react5.useRef)(null);
|
|
@@ -1755,7 +1777,8 @@ function Table({
|
|
|
1755
1777
|
const getScrollableColumnLeft = (0, import_react5.useCallback)((columnIndex) => scrollableColumnLefts[columnIndex] ?? fixedWidth, [fixedWidth, scrollableColumnLefts]);
|
|
1756
1778
|
const hasRowSelectionColumn = (0, import_react5.useMemo)(() => columns.some((column) => column.rowSelection), [columns]);
|
|
1757
1779
|
const rowSelectionMode = typeof rowSelection === "object" ? rowSelection.mode ?? "multiple" : "multiple";
|
|
1758
|
-
const
|
|
1780
|
+
const summarySignature = (0, import_react5.useMemo)(() => getSummarySignature(columns), [columns]);
|
|
1781
|
+
const hasSummaryRow = rows.length > 0 && summaryEnabled && summarySignature.length > 0;
|
|
1759
1782
|
const topSummaryHeight = hasSummaryRow && summaryPosition === "top" ? rowHeight : 0;
|
|
1760
1783
|
const bottomSummaryHeight = hasSummaryRow && summaryPosition === "bottom" ? rowHeight : 0;
|
|
1761
1784
|
const bodyTop = headerHeight + topSummaryHeight;
|
|
@@ -1764,21 +1787,21 @@ function Table({
|
|
|
1764
1787
|
const effectiveHeight = autoHeight ? Math.max(bodyTop + bottomSummaryHeight, Math.min(resolvedHeight, realContentHeight)) : resolvedHeight;
|
|
1765
1788
|
const renderHeight = Math.max(0, effectiveHeight - bottomSummaryHeight);
|
|
1766
1789
|
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.
|
|
1790
|
+
const [summaryState, setSummaryState] = (0, import_react5.useState)(() => ({ signature: "", rows: null, values: /* @__PURE__ */ new Map(), pending: false }));
|
|
1791
|
+
const summaryPending = hasSummaryRow && (loading || summaryState.pending || summaryState.signature !== summarySignature || summaryState.rows !== rows);
|
|
1792
|
+
const summaryValues = hasSummaryRow && summaryState.signature === summarySignature && summaryState.rows === rows ? summaryState.values : /* @__PURE__ */ new Map();
|
|
1770
1793
|
(0, import_react5.useEffect)(() => {
|
|
1771
1794
|
let cancelled = false;
|
|
1772
1795
|
if (!hasSummaryRow) {
|
|
1773
|
-
setSummaryState((current) => current.
|
|
1796
|
+
setSummaryState((current) => current.signature === "" && current.rows === null && current.values.size === 0 && !current.pending ? current : { signature: "", rows: null, values: /* @__PURE__ */ new Map(), pending: false });
|
|
1774
1797
|
return () => {
|
|
1775
1798
|
cancelled = true;
|
|
1776
1799
|
};
|
|
1777
1800
|
}
|
|
1778
1801
|
setSummaryState((current) => ({
|
|
1779
|
-
|
|
1802
|
+
signature: summarySignature,
|
|
1780
1803
|
rows,
|
|
1781
|
-
values: current.
|
|
1804
|
+
values: current.signature === summarySignature && current.rows === rows ? current.values : /* @__PURE__ */ new Map(),
|
|
1782
1805
|
pending: true
|
|
1783
1806
|
}));
|
|
1784
1807
|
if (loading) {
|
|
@@ -1791,13 +1814,13 @@ function Table({
|
|
|
1791
1814
|
if (cancelled) return;
|
|
1792
1815
|
const values = await calculateSummaryValues(columns, rows);
|
|
1793
1816
|
if (cancelled) return;
|
|
1794
|
-
setSummaryState({
|
|
1817
|
+
setSummaryState({ signature: summarySignature, rows, values, pending: false });
|
|
1795
1818
|
};
|
|
1796
1819
|
void run();
|
|
1797
1820
|
return () => {
|
|
1798
1821
|
cancelled = true;
|
|
1799
1822
|
};
|
|
1800
|
-
}, [
|
|
1823
|
+
}, [hasSummaryRow, loading, rows, summarySignature]);
|
|
1801
1824
|
const domRange = (0, import_react5.useMemo)(() => {
|
|
1802
1825
|
if (!isVirtualized) return { rowStart: 0, rowEnd: rows.length, columnStart: 0, columnEnd: columns.length };
|
|
1803
1826
|
const currentScroll2 = scrollRef.current;
|
|
@@ -1944,6 +1967,158 @@ function Table({
|
|
|
1944
1967
|
const scheduleDraw = (0, import_react5.useCallback)(() => {
|
|
1945
1968
|
if (frameRef.current === null) frameRef.current = requestAnimationFrame(draw);
|
|
1946
1969
|
}, [draw]);
|
|
1970
|
+
const drawImmediately = (0, import_react5.useCallback)(() => {
|
|
1971
|
+
if (frameRef.current !== null) cancelAnimationFrame(frameRef.current);
|
|
1972
|
+
frameRef.current = null;
|
|
1973
|
+
draw();
|
|
1974
|
+
}, [draw]);
|
|
1975
|
+
const getSelectionHorizontalVisibility = (0, import_react5.useCallback)((scrollLeft) => {
|
|
1976
|
+
if (!selection || selectionRange) return "visible";
|
|
1977
|
+
const column = columns[selection.columnIndex];
|
|
1978
|
+
if (!column || column.fixed !== void 0) return "visible";
|
|
1979
|
+
const span = getCellSpan(selection.rowIndex, selection.columnIndex);
|
|
1980
|
+
const left = getScrollableColumnLeft(selection.columnIndex) - scrollLeft;
|
|
1981
|
+
const right = left + getCellDisplayWidth(selection.columnIndex, span?.colSpan ?? 1);
|
|
1982
|
+
if (right <= fixedWidth) return "hidden-left";
|
|
1983
|
+
if (left >= viewport.width - rightFixedWidth) return "hidden-right";
|
|
1984
|
+
return "visible";
|
|
1985
|
+
}, [columns, fixedWidth, getCellDisplayWidth, getCellSpan, getScrollableColumnLeft, rightFixedWidth, selection, selectionRange, viewport.width]);
|
|
1986
|
+
const getSelectionEdgeIndicator = (0, import_react5.useCallback)((scrollLeft, scrollTop) => {
|
|
1987
|
+
if (!selection || selectionRange) return null;
|
|
1988
|
+
const row = rows[selection.rowIndex];
|
|
1989
|
+
const metric = metrics[selection.columnIndex];
|
|
1990
|
+
const column = columns[selection.columnIndex];
|
|
1991
|
+
if (!row || !metric || !column || getRowKey(row, selection.rowIndex) !== selection.rowKey) return null;
|
|
1992
|
+
const span = getCellSpan(selection.rowIndex, selection.columnIndex);
|
|
1993
|
+
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;
|
|
1994
|
+
const rawRight = rawLeft + getCellDisplayWidth(selection.columnIndex, span?.colSpan ?? 1);
|
|
1995
|
+
const rawTop = bodyTop + selection.rowIndex * rowHeight - scrollTop;
|
|
1996
|
+
const rawBottom = rawTop + rowHeight * (span?.rowSpan ?? 1);
|
|
1997
|
+
const horizontalStart = column.fixed === void 0 ? fixedWidth : 0;
|
|
1998
|
+
const horizontalEnd = column.fixed === void 0 ? viewport.width - rightFixedWidth : viewport.width;
|
|
1999
|
+
const verticalStart = fixedHeader ? bodyTop : 0;
|
|
2000
|
+
const hiddenLeft = column.fixed === void 0 && rawRight <= horizontalStart;
|
|
2001
|
+
const hiddenRight = column.fixed === void 0 && rawLeft >= horizontalEnd;
|
|
2002
|
+
const hiddenTop = rawBottom <= verticalStart;
|
|
2003
|
+
const hiddenBottom = rawTop >= renderHeight;
|
|
2004
|
+
if (!hiddenLeft && !hiddenRight && !hiddenTop && !hiddenBottom) return null;
|
|
2005
|
+
const borderWidth = 2;
|
|
2006
|
+
const cornerLength = 10;
|
|
2007
|
+
const hitSlop = 6;
|
|
2008
|
+
const targetSize = borderWidth + hitSlop * 2;
|
|
2009
|
+
const rightBoundaryInset = rightFixedWidth > 0 && hasVerticalBorders ? 1 : 0;
|
|
2010
|
+
const markerX = hiddenLeft ? horizontalStart : horizontalEnd - borderWidth - rightBoundaryInset;
|
|
2011
|
+
const markerY = hiddenTop ? verticalStart : renderHeight - borderWidth;
|
|
2012
|
+
if (hiddenLeft || hiddenRight) {
|
|
2013
|
+
let markerTop = Math.max(rawTop - borderWidth, verticalStart);
|
|
2014
|
+
let markerBottom = Math.min(rawBottom + 1, renderHeight);
|
|
2015
|
+
const topClip = Math.max(0, verticalStart - (rawTop - borderWidth));
|
|
2016
|
+
const bottomClip = Math.max(0, rawBottom + 1 - renderHeight);
|
|
2017
|
+
if (topClip > 0 || bottomClip > 0) {
|
|
2018
|
+
const foldAtTop = topClip > 0;
|
|
2019
|
+
const fold = Math.min(cornerLength, foldAtTop ? topClip : bottomClip);
|
|
2020
|
+
if (fold > borderWidth) {
|
|
2021
|
+
const cornerWidth = fold;
|
|
2022
|
+
const cornerHeight = Math.max(cornerLength, markerBottom - markerTop);
|
|
2023
|
+
const cornerOnLeft = hiddenLeft;
|
|
2024
|
+
const shapeLeft = cornerOnLeft ? markerX : markerX + borderWidth - cornerWidth;
|
|
2025
|
+
const shapeTop = foldAtTop ? verticalStart : renderHeight - cornerHeight;
|
|
2026
|
+
return {
|
|
2027
|
+
side: `${foldAtTop ? "top" : "bottom"}-${cornerOnLeft ? "left" : "right"}`,
|
|
2028
|
+
orientation: "corner",
|
|
2029
|
+
style: {
|
|
2030
|
+
left: shapeLeft - hitSlop,
|
|
2031
|
+
top: shapeTop - hitSlop,
|
|
2032
|
+
width: cornerWidth + hitSlop * 2,
|
|
2033
|
+
height: cornerHeight + hitSlop * 2
|
|
2034
|
+
},
|
|
2035
|
+
corner: { width: cornerWidth, height: cornerHeight }
|
|
2036
|
+
};
|
|
2037
|
+
}
|
|
2038
|
+
}
|
|
2039
|
+
if (markerBottom <= markerTop) return null;
|
|
2040
|
+
return {
|
|
2041
|
+
side: hiddenLeft ? "left" : "right",
|
|
2042
|
+
orientation: "vertical",
|
|
2043
|
+
viewportEdge: hiddenLeft && horizontalStart === 0 ? "left" : hiddenRight && horizontalEnd === viewport.width ? "right" : void 0,
|
|
2044
|
+
style: {
|
|
2045
|
+
left: markerX - hitSlop,
|
|
2046
|
+
top: markerTop,
|
|
2047
|
+
width: targetSize,
|
|
2048
|
+
height: markerBottom - markerTop
|
|
2049
|
+
}
|
|
2050
|
+
};
|
|
2051
|
+
}
|
|
2052
|
+
const horizontalMarkerEnd = horizontalEnd - rightBoundaryInset;
|
|
2053
|
+
let markerLeft = Math.max(rawLeft - borderWidth, horizontalStart);
|
|
2054
|
+
let markerRight = Math.min(rawRight + 1, horizontalMarkerEnd);
|
|
2055
|
+
const leftClip = Math.max(0, horizontalStart - (rawLeft - borderWidth));
|
|
2056
|
+
const rightClip = Math.max(0, rawRight + 1 - horizontalMarkerEnd);
|
|
2057
|
+
if (leftClip > 0 || rightClip > 0) {
|
|
2058
|
+
const foldAtLeft = leftClip > 0;
|
|
2059
|
+
const fold = Math.min(cornerLength, foldAtLeft ? leftClip : rightClip);
|
|
2060
|
+
if (fold > borderWidth) {
|
|
2061
|
+
const cornerWidth = Math.max(cornerLength, markerRight - markerLeft);
|
|
2062
|
+
const cornerHeight = fold;
|
|
2063
|
+
const shapeLeft = foldAtLeft ? horizontalStart : horizontalMarkerEnd - cornerWidth;
|
|
2064
|
+
const shapeTop = hiddenTop ? verticalStart : renderHeight - cornerHeight;
|
|
2065
|
+
return {
|
|
2066
|
+
side: `${hiddenTop ? "top" : "bottom"}-${foldAtLeft ? "left" : "right"}`,
|
|
2067
|
+
orientation: "corner",
|
|
2068
|
+
style: {
|
|
2069
|
+
left: shapeLeft - hitSlop,
|
|
2070
|
+
top: shapeTop - hitSlop,
|
|
2071
|
+
width: cornerWidth + hitSlop * 2,
|
|
2072
|
+
height: cornerHeight + hitSlop * 2
|
|
2073
|
+
},
|
|
2074
|
+
corner: { width: cornerWidth, height: cornerHeight }
|
|
2075
|
+
};
|
|
2076
|
+
}
|
|
2077
|
+
}
|
|
2078
|
+
if (markerRight <= markerLeft) return null;
|
|
2079
|
+
return {
|
|
2080
|
+
side: hiddenTop ? "top" : "bottom",
|
|
2081
|
+
orientation: "horizontal",
|
|
2082
|
+
viewportEdge: hiddenTop && verticalStart === 0 ? "top" : hiddenBottom ? "bottom" : void 0,
|
|
2083
|
+
style: {
|
|
2084
|
+
left: markerLeft,
|
|
2085
|
+
top: markerY - hitSlop,
|
|
2086
|
+
width: markerRight - markerLeft,
|
|
2087
|
+
height: targetSize
|
|
2088
|
+
}
|
|
2089
|
+
};
|
|
2090
|
+
}, [bodyTop, columns, fixedHeader, fixedWidth, getCellDisplayWidth, getCellSpan, getRowKey, getScrollableColumnLeft, hasVerticalBorders, leftFixedOffsets, metrics, renderHeight, rightFixedOffsets, rightFixedWidth, rowHeight, rows, selection, selectionRange, viewport.width]);
|
|
2091
|
+
const syncSelectionEdgeTarget = (0, import_react5.useCallback)((scrollLeft, scrollTop) => {
|
|
2092
|
+
const target = selectionEdgeTargetRef.current;
|
|
2093
|
+
if (!target) return;
|
|
2094
|
+
const indicator = getSelectionEdgeIndicator(scrollLeft, scrollTop);
|
|
2095
|
+
if (!indicator) {
|
|
2096
|
+
target.style.visibility = "hidden";
|
|
2097
|
+
return;
|
|
2098
|
+
}
|
|
2099
|
+
const orientationChanged = !target.classList.contains(`is-${indicator.orientation}`);
|
|
2100
|
+
target.className = `rvg-selection-edge-target is-${indicator.orientation} is-${indicator.side}${indicator.viewportEdge ? ` is-viewport-${indicator.viewportEdge}` : ""}${orientationChanged ? " is-shape-syncing" : ""}`;
|
|
2101
|
+
target.style.left = `${Number(indicator.style.left)}px`;
|
|
2102
|
+
target.style.top = `${Number(indicator.style.top)}px`;
|
|
2103
|
+
target.style.width = `${Number(indicator.style.width)}px`;
|
|
2104
|
+
target.style.height = `${Number(indicator.style.height)}px`;
|
|
2105
|
+
if (indicator.corner) {
|
|
2106
|
+
target.style.setProperty("--rvg-corner-width", `${indicator.corner.width}px`);
|
|
2107
|
+
target.style.setProperty("--rvg-corner-height", `${indicator.corner.height}px`);
|
|
2108
|
+
target.style.setProperty("--rvg-corner-hover-width-extension", "4px");
|
|
2109
|
+
target.style.setProperty("--rvg-corner-hover-height-extension", "4px");
|
|
2110
|
+
} else {
|
|
2111
|
+
target.style.removeProperty("--rvg-corner-width");
|
|
2112
|
+
target.style.removeProperty("--rvg-corner-height");
|
|
2113
|
+
target.style.removeProperty("--rvg-corner-hover-width-extension");
|
|
2114
|
+
target.style.removeProperty("--rvg-corner-hover-height-extension");
|
|
2115
|
+
}
|
|
2116
|
+
target.style.visibility = "visible";
|
|
2117
|
+
if (orientationChanged) {
|
|
2118
|
+
void target.offsetWidth;
|
|
2119
|
+
target.classList.remove("is-shape-syncing");
|
|
2120
|
+
}
|
|
2121
|
+
}, [getSelectionEdgeIndicator]);
|
|
1947
2122
|
(0, import_react5.useLayoutEffect)(() => {
|
|
1948
2123
|
const element = scrollerRef.current;
|
|
1949
2124
|
if (!element) return;
|
|
@@ -2194,7 +2369,13 @@ function Table({
|
|
|
2194
2369
|
}
|
|
2195
2370
|
const nextThumbLeft = Math.max(0, Math.min(trackWidth - thumbWidth, event.clientX - trackRect.left - thumbWidth / 2));
|
|
2196
2371
|
const maxThumbLeft = Math.max(1, trackWidth - thumbWidth);
|
|
2197
|
-
scroller.scrollLeft
|
|
2372
|
+
const previousScrollLeft = scroller.scrollLeft;
|
|
2373
|
+
const nextScrollLeft = nextThumbLeft / maxThumbLeft * maxScrollLeft;
|
|
2374
|
+
const visibilityChanged = getSelectionHorizontalVisibility(previousScrollLeft) !== getSelectionHorizontalVisibility(nextScrollLeft);
|
|
2375
|
+
scroller.scrollLeft = nextScrollLeft;
|
|
2376
|
+
scrollRef.current = { left: scroller.scrollLeft, top: scroller.scrollTop };
|
|
2377
|
+
syncSelectionEdgeTarget(scroller.scrollLeft, scroller.scrollTop);
|
|
2378
|
+
if (visibilityChanged) drawImmediately();
|
|
2198
2379
|
updateCustomScrollbars();
|
|
2199
2380
|
horizontalScrollbarDragRef.current = {
|
|
2200
2381
|
pointerId: event.pointerId,
|
|
@@ -2204,7 +2385,7 @@ function Table({
|
|
|
2204
2385
|
thumbWidth,
|
|
2205
2386
|
maxScrollLeft
|
|
2206
2387
|
};
|
|
2207
|
-
}, [showCustomScrollbar, updateCustomScrollbars]);
|
|
2388
|
+
}, [drawImmediately, getSelectionHorizontalVisibility, showCustomScrollbar, syncSelectionEdgeTarget, updateCustomScrollbars]);
|
|
2208
2389
|
const handleHorizontalScrollbarPointerMove = (0, import_react5.useCallback)((event) => {
|
|
2209
2390
|
const drag = horizontalScrollbarDragRef.current;
|
|
2210
2391
|
const scroller = scrollerRef.current;
|
|
@@ -2212,9 +2393,15 @@ function Table({
|
|
|
2212
2393
|
event.preventDefault();
|
|
2213
2394
|
const maxThumbLeft = Math.max(1, drag.trackWidth - drag.thumbWidth);
|
|
2214
2395
|
const nextThumbLeft = Math.max(0, Math.min(maxThumbLeft, drag.startLeft + event.clientX - drag.startX));
|
|
2215
|
-
|
|
2396
|
+
const previousScrollLeft = scroller.scrollLeft;
|
|
2397
|
+
const nextScrollLeft = nextThumbLeft / maxThumbLeft * drag.maxScrollLeft;
|
|
2398
|
+
const visibilityChanged = getSelectionHorizontalVisibility(previousScrollLeft) !== getSelectionHorizontalVisibility(nextScrollLeft);
|
|
2399
|
+
scroller.scrollLeft = nextScrollLeft;
|
|
2400
|
+
scrollRef.current = { left: scroller.scrollLeft, top: scroller.scrollTop };
|
|
2401
|
+
syncSelectionEdgeTarget(scroller.scrollLeft, scroller.scrollTop);
|
|
2402
|
+
if (visibilityChanged) drawImmediately();
|
|
2216
2403
|
updateCustomScrollbars();
|
|
2217
|
-
}, [updateCustomScrollbars]);
|
|
2404
|
+
}, [drawImmediately, getSelectionHorizontalVisibility, syncSelectionEdgeTarget, updateCustomScrollbars]);
|
|
2218
2405
|
const handleHorizontalScrollbarPointerUp = (0, import_react5.useCallback)((event) => {
|
|
2219
2406
|
const drag = horizontalScrollbarDragRef.current;
|
|
2220
2407
|
if (!drag || drag.pointerId !== event.pointerId) return;
|
|
@@ -2229,6 +2416,7 @@ function Table({
|
|
|
2229
2416
|
const scrollDeltaX = element.scrollLeft - previousScroll.left;
|
|
2230
2417
|
const scrollDeltaY = element.scrollTop - previousScroll.top;
|
|
2231
2418
|
scrollRef.current = { left: element.scrollLeft, top: element.scrollTop };
|
|
2419
|
+
syncSelectionEdgeTarget(element.scrollLeft, element.scrollTop);
|
|
2232
2420
|
const focus = selectionFocusRef.current;
|
|
2233
2421
|
if (focus && selection && !selectionRange) {
|
|
2234
2422
|
const row = rows[selection.rowIndex];
|
|
@@ -2250,9 +2438,9 @@ function Table({
|
|
|
2250
2438
|
focus.style.display = "none";
|
|
2251
2439
|
} else {
|
|
2252
2440
|
const borderWidth = 2;
|
|
2253
|
-
const left = Math.round(Math.max(rawLeft - borderWidth, horizontalStart
|
|
2441
|
+
const left = Math.round(Math.max(rawLeft - borderWidth, horizontalStart));
|
|
2254
2442
|
const right = Math.round(Math.min(rawRight + 1, horizontalEnd, viewport.width));
|
|
2255
|
-
const top = Math.round(Math.max(rawTop - borderWidth, verticalStart
|
|
2443
|
+
const top = Math.round(Math.max(rawTop - borderWidth, verticalStart));
|
|
2256
2444
|
const bottom = Math.round(Math.min(rawBottom + 1, renderHeight));
|
|
2257
2445
|
focus.style.display = "block";
|
|
2258
2446
|
focus.style.left = `${left}px`;
|
|
@@ -2282,7 +2470,7 @@ function Table({
|
|
|
2282
2470
|
setHoveredCellTooltip(null);
|
|
2283
2471
|
scheduleDraw();
|
|
2284
2472
|
setEditing(null);
|
|
2285
|
-
}, [bodyTop, columns, renderHeight, fixedHeader, fixedWidth, getCellDisplayWidth, getCellSpan, getRowKey, getScrollableColumnLeft, metrics, rightFixedOffsets, rightFixedWidth, rowHeight, rows, scheduleDraw, selection, selectionRange, showCustomScrollbar, updateCustomScrollbars, viewport.width]);
|
|
2473
|
+
}, [bodyTop, columns, renderHeight, fixedHeader, fixedWidth, getCellDisplayWidth, getCellSpan, getRowKey, getScrollableColumnLeft, metrics, rightFixedOffsets, rightFixedWidth, rowHeight, rows, scheduleDraw, selection, selectionRange, showCustomScrollbar, syncSelectionEdgeTarget, updateCustomScrollbars, viewport.width]);
|
|
2286
2474
|
const locateColumn = (0, import_react5.useCallback)((clientX) => {
|
|
2287
2475
|
const canvas = canvasRef.current;
|
|
2288
2476
|
if (!canvas) return -1;
|
|
@@ -2370,6 +2558,30 @@ function Table({
|
|
|
2370
2558
|
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
2559
|
}, [columns, getScrollableColumnLeft, leftFixedOffsets, metrics, rightFixedOffsets, viewport.width]);
|
|
2372
2560
|
const getHeaderCellWidth = (0, import_react5.useCallback)((cell) => cell.leaf ? metrics[cell.startIndex]?.width ?? 0 : getCellDisplayWidth(cell.startIndex, cell.endIndex - cell.startIndex + 1), [getCellDisplayWidth, metrics]);
|
|
2561
|
+
const getHeaderCellEdgeFromMetrics = (0, import_react5.useCallback)((startIndex, endIndex, edge, nextMetrics) => {
|
|
2562
|
+
const fixedSide = columns[startIndex]?.fixed;
|
|
2563
|
+
const width2 = nextMetrics.slice(startIndex, endIndex + 1).reduce((total, metric) => total + metric.width, 0);
|
|
2564
|
+
let left;
|
|
2565
|
+
if (fixedSide === "left") {
|
|
2566
|
+
left = 0;
|
|
2567
|
+
for (let index = 0; index < startIndex; index += 1) {
|
|
2568
|
+
if (columns[index].fixed === "left") left += nextMetrics[index]?.width ?? 0;
|
|
2569
|
+
}
|
|
2570
|
+
} else if (fixedSide === "right") {
|
|
2571
|
+
let rightOffset = 0;
|
|
2572
|
+
for (let index = columns.length - 1; index > startIndex; index -= 1) {
|
|
2573
|
+
if (columns[index].fixed === "right") rightOffset += nextMetrics[index]?.width ?? 0;
|
|
2574
|
+
}
|
|
2575
|
+
left = viewport.width - rightOffset - width2;
|
|
2576
|
+
} else {
|
|
2577
|
+
left = 0;
|
|
2578
|
+
for (let index = 0; index < startIndex; index += 1) {
|
|
2579
|
+
if (columns[index].fixed === void 0) left += nextMetrics[index]?.width ?? 0;
|
|
2580
|
+
}
|
|
2581
|
+
left += fixedWidth - scrollRef.current.left;
|
|
2582
|
+
}
|
|
2583
|
+
return left + (edge === "right" ? width2 : 0);
|
|
2584
|
+
}, [columns, fixedWidth, viewport.width]);
|
|
2373
2585
|
const locateHeaderResizeHit = (0, import_react5.useCallback)((clientX, clientY) => {
|
|
2374
2586
|
if (!columnResizable || !canvasRef.current) return null;
|
|
2375
2587
|
const rect = canvasRef.current.getBoundingClientRect();
|
|
@@ -2380,6 +2592,7 @@ function Table({
|
|
|
2380
2592
|
const level = getHeaderLevelAtY(localY, headerY);
|
|
2381
2593
|
let closest = null;
|
|
2382
2594
|
let distance = 6;
|
|
2595
|
+
let priority = -1;
|
|
2383
2596
|
for (const cell of headerCells) {
|
|
2384
2597
|
if (cell.level !== level) continue;
|
|
2385
2598
|
if (columns[cell.startIndex]?.rowSelection || columns[cell.startIndex]?.rowDragHandle || columns[cell.startIndex]?.rowNumber) continue;
|
|
@@ -2387,8 +2600,10 @@ function Table({
|
|
|
2387
2600
|
const edge = fixedSide === "right" && cell.leaf ? "left" : "right";
|
|
2388
2601
|
const edgeX = getHeaderCellLeft(cell) + (edge === "right" ? getHeaderCellWidth(cell) : 0);
|
|
2389
2602
|
const nextDistance = Math.abs(localX - edgeX);
|
|
2390
|
-
|
|
2603
|
+
const nextPriority = fixedSide === "right" ? 2 : fixedSide === "left" ? 1 : 0;
|
|
2604
|
+
if (nextDistance < distance || nextDistance === distance && nextPriority > priority) {
|
|
2391
2605
|
distance = nextDistance;
|
|
2606
|
+
priority = nextPriority;
|
|
2392
2607
|
closest = { cell, edge };
|
|
2393
2608
|
}
|
|
2394
2609
|
}
|
|
@@ -2600,6 +2815,10 @@ function Table({
|
|
|
2600
2815
|
columnDragPreviewRef.current = { sourceIndex, targetIndex: destinationIndex };
|
|
2601
2816
|
const targetLeft = Number(target?.targetLeft);
|
|
2602
2817
|
const targetWidth = Number(target?.targetWidth);
|
|
2818
|
+
if (!Number.isFinite(targetLeft) || !Number.isFinite(targetWidth)) {
|
|
2819
|
+
setDragGuide(null);
|
|
2820
|
+
return;
|
|
2821
|
+
}
|
|
2603
2822
|
const guideTop = headerRowOffsets[Number(source.data.headerLevel)] ?? 0;
|
|
2604
2823
|
setDragGuide(edge === "right" ? targetLeft + targetWidth : targetLeft, guideTop);
|
|
2605
2824
|
},
|
|
@@ -2997,18 +3216,28 @@ function Table({
|
|
|
2997
3216
|
const editorStyle = (0, import_react5.useMemo)(() => {
|
|
2998
3217
|
if (!editing) return void 0;
|
|
2999
3218
|
const metric = metrics[editing.columnIndex];
|
|
3000
|
-
const
|
|
3219
|
+
const column = columns[editing.columnIndex];
|
|
3220
|
+
if (!metric || !column) return void 0;
|
|
3221
|
+
const fixedSide = column.fixed;
|
|
3001
3222
|
const span = getCellSpan(editing.rowIndex, editing.columnIndex);
|
|
3002
3223
|
const cellWidth = getCellDisplayWidth(editing.columnIndex, span?.colSpan ?? 1);
|
|
3003
3224
|
const cellHeight = rowHeight * (span?.rowSpan ?? 1);
|
|
3004
3225
|
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;
|
|
3226
|
+
const cellTop = bodyTop + editing.rowIndex * rowHeight - scrollRef.current.top;
|
|
3227
|
+
const horizontalStart = fixedSide === void 0 ? fixedWidth : 0;
|
|
3228
|
+
const horizontalEnd = fixedSide === void 0 ? viewport.width - rightFixedWidth : viewport.width;
|
|
3229
|
+
const verticalStart = fixedHeader ? bodyTop : 0;
|
|
3230
|
+
const visibleLeft = Math.max(cellLeft, horizontalStart);
|
|
3231
|
+
const visibleRight = Math.min(cellLeft + cellWidth, horizontalEnd, viewport.width);
|
|
3232
|
+
const visibleTop = Math.max(cellTop, verticalStart);
|
|
3233
|
+
const visibleBottom = Math.min(cellTop + cellHeight, renderHeight);
|
|
3005
3234
|
return {
|
|
3006
|
-
left:
|
|
3007
|
-
top:
|
|
3008
|
-
width:
|
|
3009
|
-
height:
|
|
3235
|
+
left: visibleLeft,
|
|
3236
|
+
top: visibleTop,
|
|
3237
|
+
width: Math.max(0, visibleRight - visibleLeft),
|
|
3238
|
+
height: Math.max(0, visibleBottom - visibleTop)
|
|
3010
3239
|
};
|
|
3011
|
-
}, [bodyTop, columns, editing, fixedHeader, fixedWidth, getCellDisplayWidth, getCellSpan, getScrollableColumnLeft, leftFixedOffsets, metrics, rightFixedOffsets, rowHeight, viewport.width]);
|
|
3240
|
+
}, [bodyTop, columns, editing, fixedHeader, fixedWidth, getCellDisplayWidth, getCellSpan, getScrollableColumnLeft, leftFixedOffsets, metrics, renderHeight, rightFixedOffsets, rightFixedWidth, rowHeight, viewport.width]);
|
|
3012
3241
|
const handleColumnPointerDown = (0, import_react5.useCallback)((event) => {
|
|
3013
3242
|
const rect = event.currentTarget.getBoundingClientRect();
|
|
3014
3243
|
const localY = event.clientY - rect.top;
|
|
@@ -3028,9 +3257,10 @@ function Table({
|
|
|
3028
3257
|
columnIndex: resizeIndex,
|
|
3029
3258
|
startX: event.clientX,
|
|
3030
3259
|
startWidth: startWidths.reduce((total, width2) => total + width2, 0),
|
|
3031
|
-
startGuideX,
|
|
3032
3260
|
guideTop: headerRowOffsets[resizeCell.level] ?? 0,
|
|
3033
3261
|
resizeEdge,
|
|
3262
|
+
resizeStartIndex: resizeCell.startIndex,
|
|
3263
|
+
resizeEndIndex: resizeCell.endIndex,
|
|
3034
3264
|
resizeIndices,
|
|
3035
3265
|
startWidths
|
|
3036
3266
|
};
|
|
@@ -3047,6 +3277,12 @@ function Table({
|
|
|
3047
3277
|
const minWidth = getMinimumColumnWidth(column, columnDraggable);
|
|
3048
3278
|
const pointerDelta = Math.round(event.clientX - drag.startX);
|
|
3049
3279
|
const delta = drag.resizeEdge === "left" ? -pointerDelta : pointerDelta;
|
|
3280
|
+
const setGuideFromWidths = (nextWidths) => {
|
|
3281
|
+
const widthByIndex = new Map(drag.resizeIndices.map((columnIndex, index) => [columnIndex, nextWidths[index]]));
|
|
3282
|
+
const nextColumns = columns.map((column2, index) => widthByIndex.has(index) ? { ...column2, width: widthByIndex.get(index) } : column2);
|
|
3283
|
+
const nextMetrics = buildColumnMetrics(nextColumns, { columnDraggable, viewportWidth: viewport.width });
|
|
3284
|
+
setResizeGuideX(getHeaderCellEdgeFromMetrics(drag.resizeStartIndex, drag.resizeEndIndex, drag.resizeEdge, nextMetrics));
|
|
3285
|
+
};
|
|
3050
3286
|
if (drag.resizeIndices.length > 1) {
|
|
3051
3287
|
const minWidths = drag.resizeIndices.map((index) => getMinimumColumnWidth(columns[index], columnDraggable));
|
|
3052
3288
|
const minTotalWidth = minWidths.reduce((total, width3) => total + width3, 0);
|
|
@@ -3063,13 +3299,13 @@ function Table({
|
|
|
3063
3299
|
drag.resizeIndices.forEach((columnIndex, index) => {
|
|
3064
3300
|
resizeColumn(columns[columnIndex].key, nextWidths[index]);
|
|
3065
3301
|
});
|
|
3066
|
-
|
|
3302
|
+
setGuideFromWidths(nextWidths);
|
|
3067
3303
|
return;
|
|
3068
3304
|
}
|
|
3069
3305
|
const width2 = Math.max(minWidth, Math.round(drag.startWidth + delta));
|
|
3070
3306
|
resizeColumn(column.key, width2);
|
|
3071
|
-
|
|
3072
|
-
}, [columnDraggable, columns, resizeColumn]);
|
|
3307
|
+
setGuideFromWidths([width2]);
|
|
3308
|
+
}, [columnDraggable, columns, getHeaderCellEdgeFromMetrics, resizeColumn, viewport.width]);
|
|
3073
3309
|
const handleColumnPointerUp = (0, import_react5.useCallback)((event) => {
|
|
3074
3310
|
const drag = columnDragRef.current;
|
|
3075
3311
|
if (!drag) return;
|
|
@@ -3650,9 +3886,9 @@ function Table({
|
|
|
3650
3886
|
const verticalStart = fixedHeader ? bodyTop : 0;
|
|
3651
3887
|
if (rawRight <= horizontalStart || rawLeft >= horizontalEnd || rawBottom <= verticalStart || rawTop >= renderHeight) return null;
|
|
3652
3888
|
const borderWidth = 2;
|
|
3653
|
-
const left = Math.round(Math.max(rawLeft - borderWidth, horizontalStart
|
|
3889
|
+
const left = Math.round(Math.max(rawLeft - borderWidth, horizontalStart));
|
|
3654
3890
|
const right = Math.round(Math.min(rawRight + 1, horizontalEnd, viewport.width));
|
|
3655
|
-
const top = Math.round(Math.max(rawTop - borderWidth, verticalStart
|
|
3891
|
+
const top = Math.round(Math.max(rawTop - borderWidth, verticalStart));
|
|
3656
3892
|
const bottom = Math.round(Math.min(rawBottom + 1, renderHeight));
|
|
3657
3893
|
return {
|
|
3658
3894
|
left,
|
|
@@ -3661,6 +3897,19 @@ function Table({
|
|
|
3661
3897
|
height: Math.max(0, bottom - top)
|
|
3662
3898
|
};
|
|
3663
3899
|
})();
|
|
3900
|
+
const selectionEdgeIndicator = getSelectionEdgeIndicator(scrollPosition.left, scrollPosition.top);
|
|
3901
|
+
const selectionEdgeStyle = selectionEdgeIndicator ? {
|
|
3902
|
+
...selectionEdgeIndicator.style,
|
|
3903
|
+
...selectionEdgeIndicator.corner ? {
|
|
3904
|
+
"--rvg-corner-width": `${selectionEdgeIndicator.corner.width}px`,
|
|
3905
|
+
"--rvg-corner-height": `${selectionEdgeIndicator.corner.height}px`,
|
|
3906
|
+
"--rvg-corner-hover-width-extension": "4px",
|
|
3907
|
+
"--rvg-corner-hover-height-extension": "4px"
|
|
3908
|
+
} : null
|
|
3909
|
+
} : void 0;
|
|
3910
|
+
(0, import_react5.useLayoutEffect)(() => {
|
|
3911
|
+
syncSelectionEdgeTarget(scrollPosition.left, scrollPosition.top);
|
|
3912
|
+
}, [scrollPosition.left, scrollPosition.top, syncSelectionEdgeTarget]);
|
|
3664
3913
|
const handleContextMenu = (event) => {
|
|
3665
3914
|
event.preventDefault();
|
|
3666
3915
|
event.stopPropagation();
|
|
@@ -4108,6 +4357,27 @@ function Table({
|
|
|
4108
4357
|
}
|
|
4109
4358
|
),
|
|
4110
4359
|
selectionOutlineStyle && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { ref: selectionFocusRef, className: "rvg-selection-focus", style: selectionOutlineStyle, "aria-hidden": "true" }),
|
|
4360
|
+
selectionEdgeIndicator && selection && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
4361
|
+
"button",
|
|
4362
|
+
{
|
|
4363
|
+
ref: selectionEdgeTargetRef,
|
|
4364
|
+
type: "button",
|
|
4365
|
+
className: `rvg-selection-edge-target is-${selectionEdgeIndicator.orientation} is-${selectionEdgeIndicator.side}${selectionEdgeIndicator.viewportEdge ? ` is-viewport-${selectionEdgeIndicator.viewportEdge}` : ""}`,
|
|
4366
|
+
style: selectionEdgeStyle,
|
|
4367
|
+
"aria-label": labels.revealSelectedCell,
|
|
4368
|
+
title: labels.revealSelectedCell,
|
|
4369
|
+
onPointerDown: (event) => {
|
|
4370
|
+
event.preventDefault();
|
|
4371
|
+
event.stopPropagation();
|
|
4372
|
+
},
|
|
4373
|
+
onClick: (event) => {
|
|
4374
|
+
event.stopPropagation();
|
|
4375
|
+
scrollerRef.current?.focus({ preventScroll: true });
|
|
4376
|
+
revealCell(selection);
|
|
4377
|
+
},
|
|
4378
|
+
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" }) }) })
|
|
4379
|
+
}
|
|
4380
|
+
),
|
|
4111
4381
|
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
4382
|
const column = columns[contextMenu.columnIndex];
|
|
4113
4383
|
const headerContext = { column, columnIndex: contextMenu.columnIndex };
|
|
@@ -4432,8 +4702,8 @@ function Table({
|
|
|
4432
4702
|
column.key
|
|
4433
4703
|
);
|
|
4434
4704
|
}) }, 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 } })
|
|
4705
|
+
fixedWidth > 0 && currentScroll.left > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "rvg-loading-fixed-shadow is-left", style: { left: fixedWidth } }),
|
|
4706
|
+
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
4707
|
] }),
|
|
4438
4708
|
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
4709
|
] });
|