@lensui/lens-table 0.1.77 → 0.1.79
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 +119 -150
- package/dist/index.css +24 -6
- package/dist/index.js +119 -150
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -332,6 +332,19 @@ function LoadingSpinnerIcon() {
|
|
|
332
332
|
|
|
333
333
|
// src/components/editors/ChoiceEditor.tsx
|
|
334
334
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
335
|
+
var SEARCHABLE_CHOICE_POPUP_MAX_WIDTH = 360;
|
|
336
|
+
var SEARCHABLE_CHOICE_POPUP_HORIZONTAL_PADDING = 44;
|
|
337
|
+
var SEARCHABLE_CHOICE_POPUP_VIEWPORT_GAP = 8;
|
|
338
|
+
function getSearchableChoicePopupHorizontalLayout(anchorLeft, anchorWidth, longestLabelWidth, viewportWidth) {
|
|
339
|
+
const availableWidth = Math.max(0, viewportWidth - SEARCHABLE_CHOICE_POPUP_VIEWPORT_GAP * 2);
|
|
340
|
+
const desiredWidth = Math.max(anchorWidth, longestLabelWidth + SEARCHABLE_CHOICE_POPUP_HORIZONTAL_PADDING);
|
|
341
|
+
const width = Math.min(desiredWidth, SEARCHABLE_CHOICE_POPUP_MAX_WIDTH, availableWidth);
|
|
342
|
+
const left = Math.max(
|
|
343
|
+
SEARCHABLE_CHOICE_POPUP_VIEWPORT_GAP,
|
|
344
|
+
Math.min(anchorLeft, viewportWidth - SEARCHABLE_CHOICE_POPUP_VIEWPORT_GAP - width)
|
|
345
|
+
);
|
|
346
|
+
return { left, width };
|
|
347
|
+
}
|
|
335
348
|
function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownHeight, style, labels, onChange, onCommit, onCancel }) {
|
|
336
349
|
const editorRef = (0, import_react2.useRef)(null);
|
|
337
350
|
const popupRef = (0, import_react2.useRef)(null);
|
|
@@ -359,14 +372,24 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
|
|
|
359
372
|
const positionPopup = () => {
|
|
360
373
|
const rect = editorRef.current?.getBoundingClientRect();
|
|
361
374
|
if (!rect) return;
|
|
375
|
+
const longestLabelWidth = Math.max(
|
|
376
|
+
0,
|
|
377
|
+
...Array.from(popupRef.current?.querySelectorAll(".rvg-choice-item > span") ?? []).map((label) => label.scrollWidth)
|
|
378
|
+
);
|
|
379
|
+
const horizontal = getSearchableChoicePopupHorizontalLayout(
|
|
380
|
+
rect.left,
|
|
381
|
+
rect.width,
|
|
382
|
+
longestLabelWidth,
|
|
383
|
+
window.innerWidth
|
|
384
|
+
);
|
|
362
385
|
const availableBelow = window.innerHeight - rect.bottom - 8;
|
|
363
386
|
const availableAbove = rect.top - 8;
|
|
364
387
|
if (availableBelow < 120 && availableAbove > availableBelow) {
|
|
365
388
|
setPopupStyle({
|
|
366
389
|
position: "fixed",
|
|
367
390
|
bottom: window.innerHeight - rect.top + 4,
|
|
368
|
-
left:
|
|
369
|
-
width:
|
|
391
|
+
left: horizontal.left,
|
|
392
|
+
width: horizontal.width,
|
|
370
393
|
maxHeight: Math.min(maxDropdownHeight, availableAbove),
|
|
371
394
|
visibility: popupReadyRef.current ? "visible" : "hidden"
|
|
372
395
|
});
|
|
@@ -375,8 +398,8 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
|
|
|
375
398
|
setPopupStyle({
|
|
376
399
|
position: "fixed",
|
|
377
400
|
top: rect.bottom + 4,
|
|
378
|
-
left:
|
|
379
|
-
width:
|
|
401
|
+
left: horizontal.left,
|
|
402
|
+
width: horizontal.width,
|
|
380
403
|
maxHeight: Math.min(maxDropdownHeight, Math.max(80, availableBelow)),
|
|
381
404
|
visibility: popupReadyRef.current ? "visible" : "hidden"
|
|
382
405
|
});
|
|
@@ -884,7 +907,11 @@ function TextEditor({ value, type, min, max, integer = false, style, labels, onC
|
|
|
884
907
|
if (type === "number" && integer && next !== "" && !/^-?\d+$/.test(next)) return;
|
|
885
908
|
onChange(next);
|
|
886
909
|
},
|
|
887
|
-
onBlur:
|
|
910
|
+
onBlur: (event) => {
|
|
911
|
+
const nextTarget = event.relatedTarget;
|
|
912
|
+
if (nextTarget instanceof Element && nextTarget.closest("[data-rvg-preserve-edit]")) return;
|
|
913
|
+
commitValue();
|
|
914
|
+
},
|
|
888
915
|
onKeyDown: handleKeyDown
|
|
889
916
|
}
|
|
890
917
|
),
|
|
@@ -968,25 +995,6 @@ function TextAreaEditor({ value, title, maxLength, style, labels, onChange, onCo
|
|
|
968
995
|
] });
|
|
969
996
|
}
|
|
970
997
|
|
|
971
|
-
// src/icons/domIcons.ts
|
|
972
|
-
function createRowDragHandleSvg() {
|
|
973
|
-
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
974
|
-
svg.setAttribute("viewBox", "0 0 16 16");
|
|
975
|
-
for (const [cx, cy] of [[5, 4], [11, 4], [5, 8], [11, 8], [5, 12], [11, 12]]) {
|
|
976
|
-
const circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
|
|
977
|
-
circle.setAttribute("cx", String(cx));
|
|
978
|
-
circle.setAttribute("cy", String(cy));
|
|
979
|
-
circle.setAttribute("r", "1");
|
|
980
|
-
svg.appendChild(circle);
|
|
981
|
-
}
|
|
982
|
-
return svg;
|
|
983
|
-
}
|
|
984
|
-
|
|
985
|
-
// src/Table.tsx
|
|
986
|
-
var import_adapter = require("@atlaskit/pragmatic-drag-and-drop/element/adapter");
|
|
987
|
-
var import_set_custom_native_drag_preview = require("@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview");
|
|
988
|
-
var import_closest_edge = require("@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge");
|
|
989
|
-
|
|
990
998
|
// src/core/format.ts
|
|
991
999
|
function getDisplayLabel(column, row, rowIndex) {
|
|
992
1000
|
const value = column.dataIndex === void 0 ? void 0 : row[column.dataIndex];
|
|
@@ -1298,7 +1306,7 @@ function paintGrid(options) {
|
|
|
1298
1306
|
ctx.fillStyle = isAxisSelected ? getAxisSelectionFill(rowIndex, column.key) : colors.columnDropTargetFill;
|
|
1299
1307
|
ctx.fillRect(x, y, cellWidth, cellHeight);
|
|
1300
1308
|
}
|
|
1301
|
-
ctx.fillStyle = selectedRowKeys.has(rowKey) ? getAxisSelectionFill(rowIndex, column.key) : colors.grid;
|
|
1309
|
+
ctx.fillStyle = selectedRowKeys.has(rowKey) ? getAxisSelectionFill(rowIndex, column.key) : isRangeCell ? colors.selectionFill : colors.grid;
|
|
1302
1310
|
if (!verticalBorderless && !(frameBorderless && columnIndex + colSpan >= columns.length)) {
|
|
1303
1311
|
ctx.fillRect(x + cellWidth - 1, y, 1, cellHeight);
|
|
1304
1312
|
}
|
|
@@ -2068,6 +2076,7 @@ function TableInner({
|
|
|
2068
2076
|
const columnDragRef = (0, import_react8.useRef)(null);
|
|
2069
2077
|
const columnOrderDragRef = (0, import_react8.useRef)(null);
|
|
2070
2078
|
const columnOrderLongPressTimerRef = (0, import_react8.useRef)(null);
|
|
2079
|
+
const rowOrderDragRef = (0, import_react8.useRef)(null);
|
|
2071
2080
|
const dragGuideRef = (0, import_react8.useRef)(null);
|
|
2072
2081
|
const rowDragGuideRef = (0, import_react8.useRef)(null);
|
|
2073
2082
|
const selectionFocusRef = (0, import_react8.useRef)(null);
|
|
@@ -2122,6 +2131,7 @@ function TableInner({
|
|
|
2122
2131
|
const [editing, setEditing] = (0, import_react8.useState)(null);
|
|
2123
2132
|
const [draft, setDraft] = (0, import_react8.useState)("");
|
|
2124
2133
|
const [rowDragPreview, setRowDragPreview] = (0, import_react8.useState)(null);
|
|
2134
|
+
const [liftedRowPreview, setLiftedRowPreview] = (0, import_react8.useState)(null);
|
|
2125
2135
|
const [columnDragPreview, setColumnDragPreview] = (0, import_react8.useState)(null);
|
|
2126
2136
|
const [columnDropTarget, setColumnDropTarget] = (0, import_react8.useState)(null);
|
|
2127
2137
|
(0, import_react8.useEffect)(() => {
|
|
@@ -3368,131 +3378,66 @@ function TableInner({
|
|
|
3368
3378
|
const rowIndex = Math.floor((localY - bodyTop + scrollRef.current.top) / rowHeight);
|
|
3369
3379
|
return rowIndex >= 0 && rowIndex < rows.length ? rowIndex : -1;
|
|
3370
3380
|
}, [bodyTop, rowHeight, rows.length]);
|
|
3371
|
-
(0, import_react8.
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
const
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
const canvasRect = canvas.getBoundingClientRect();
|
|
3384
|
-
const input = location.current.input;
|
|
3385
|
-
const previewOffset = {
|
|
3386
|
-
x: Math.max(0, Math.min(canvasRect.width, input.clientX - canvasRect.left)) + 2,
|
|
3387
|
-
y: Math.max(0, Math.min(rowHeight, input.clientY - canvasRect.top - bodyTop - sourceIndex * rowHeight + scrollRef.current.top)) + 2
|
|
3388
|
-
};
|
|
3389
|
-
(0, import_set_custom_native_drag_preview.setCustomNativeDragPreview)({
|
|
3390
|
-
nativeSetDragImage,
|
|
3391
|
-
getOffset: () => previewOffset,
|
|
3392
|
-
render: ({ container }) => {
|
|
3393
|
-
const frame = document.createElement("div");
|
|
3394
|
-
frame.className = "rvg-row-drag-preview-frame";
|
|
3395
|
-
frame.style.width = `${canvasRect.width + 4}px`;
|
|
3396
|
-
frame.style.height = `${rowHeight + 4}px`;
|
|
3397
|
-
const preview = document.createElement("div");
|
|
3398
|
-
preview.className = "rvg-row-drag-preview";
|
|
3399
|
-
preview.style.width = `${canvasRect.width}px`;
|
|
3400
|
-
preview.style.height = `${rowHeight}px`;
|
|
3401
|
-
const row = rows[sourceIndex];
|
|
3402
|
-
const rowKey2 = getRowKey(row, sourceIndex);
|
|
3403
|
-
columns.forEach((column, columnIndex) => {
|
|
3404
|
-
const left = getDisplayedColumnLeft(columnIndex);
|
|
3405
|
-
const columnWidth = metrics[columnIndex].width;
|
|
3406
|
-
if (left + columnWidth <= 0 || left >= canvasRect.width) return;
|
|
3407
|
-
const cell = document.createElement("div");
|
|
3408
|
-
cell.className = "rvg-row-drag-preview-cell";
|
|
3409
|
-
cell.style.left = `${left}px`;
|
|
3410
|
-
cell.style.width = `${columnWidth}px`;
|
|
3411
|
-
cell.style.justifyContent = column.align === "right" ? "flex-end" : column.align === "center" ? "center" : "flex-start";
|
|
3412
|
-
if (column.rowDragHandle && !column.rowSelection) {
|
|
3413
|
-
cell.appendChild(createRowDragHandleSvg());
|
|
3414
|
-
} else if (column.rowSelection) {
|
|
3415
|
-
if (column.rowSelectionIndicator !== "none") {
|
|
3416
|
-
const checkbox = document.createElement("span");
|
|
3417
|
-
checkbox.className = selectedRowKeySet.has(rowKey2) ? "rvg-preview-checkbox is-checked" : "rvg-preview-checkbox";
|
|
3418
|
-
checkbox.textContent = selectedRowKeySet.has(rowKey2) ? "\u2713" : "";
|
|
3419
|
-
cell.appendChild(checkbox);
|
|
3420
|
-
}
|
|
3421
|
-
} else {
|
|
3422
|
-
cell.textContent = getCellLabel(sourceIndex, columnIndex);
|
|
3423
|
-
}
|
|
3424
|
-
if (selection?.rowKey === rowKey2 && selection.columnKey === column.key) cell.classList.add("is-selected");
|
|
3425
|
-
preview.appendChild(cell);
|
|
3426
|
-
});
|
|
3427
|
-
frame.appendChild(preview);
|
|
3428
|
-
container.appendChild(frame);
|
|
3429
|
-
return () => frame.remove();
|
|
3430
|
-
}
|
|
3431
|
-
});
|
|
3432
|
-
},
|
|
3433
|
-
onDragStart: ({ source }) => {
|
|
3434
|
-
const sourceIndex = Number(source.data.sourceIndex);
|
|
3435
|
-
suppressClickRef.current = true;
|
|
3436
|
-
hideDragTooltips();
|
|
3437
|
-
document.documentElement.classList.add("rvg-is-dragging");
|
|
3438
|
-
canvas.style.cursor = "move";
|
|
3439
|
-
setRowDragPreview({ sourceIndex, targetIndex: sourceIndex });
|
|
3440
|
-
},
|
|
3441
|
-
onDrag: ({ source, location }) => {
|
|
3442
|
-
const target = location.current.dropTargets[0]?.data;
|
|
3443
|
-
const sourceIndex = Number(source.data.sourceIndex);
|
|
3444
|
-
const rawTargetIndex = Number(target?.targetIndex);
|
|
3445
|
-
if (!Number.isInteger(rawTargetIndex)) {
|
|
3446
|
-
setRowDragPreview(null);
|
|
3447
|
-
setRowDragGuide(null);
|
|
3448
|
-
return;
|
|
3449
|
-
}
|
|
3450
|
-
const edge = target?.rowEdge;
|
|
3451
|
-
let targetIndex = rawTargetIndex + (edge === "bottom" ? 1 : 0);
|
|
3452
|
-
if (sourceIndex < targetIndex) targetIndex -= 1;
|
|
3453
|
-
targetIndex = Math.max(0, Math.min(rows.length - 1, targetIndex));
|
|
3454
|
-
setRowDragPreview((current) => current?.sourceIndex === sourceIndex && current.targetIndex === targetIndex ? current : { sourceIndex, targetIndex });
|
|
3455
|
-
setRowDragGuide(bodyTop + rawTargetIndex * rowHeight - scrollRef.current.top + (edge === "bottom" ? rowHeight : 0));
|
|
3456
|
-
},
|
|
3457
|
-
onDrop: ({ source, location }) => {
|
|
3458
|
-
const target = location.current.dropTargets[0]?.data;
|
|
3459
|
-
const sourceIndex = Number(source.data.sourceIndex);
|
|
3460
|
-
const rawTargetIndex = Number(target?.targetIndex);
|
|
3461
|
-
let targetIndex = rawTargetIndex + (target?.rowEdge === "bottom" ? 1 : 0);
|
|
3462
|
-
if (sourceIndex < targetIndex) targetIndex -= 1;
|
|
3463
|
-
targetIndex = Math.max(0, Math.min(rows.length - 1, targetIndex));
|
|
3464
|
-
scrollerRef.current?.classList.add("rvg-row-drop-settling");
|
|
3465
|
-
setRowDragPreview(null);
|
|
3466
|
-
setRowDragGuide(null);
|
|
3467
|
-
document.documentElement.classList.remove("rvg-is-dragging");
|
|
3468
|
-
canvas.style.cursor = "default";
|
|
3469
|
-
if (Number.isInteger(rawTargetIndex) && sourceIndex !== targetIndex) applyRowOrder(sourceIndex, targetIndex);
|
|
3470
|
-
requestAnimationFrame(() => {
|
|
3471
|
-
requestAnimationFrame(() => scrollerRef.current?.classList.remove("rvg-row-drop-settling"));
|
|
3472
|
-
});
|
|
3473
|
-
window.setTimeout(() => {
|
|
3474
|
-
suppressClickRef.current = false;
|
|
3475
|
-
}, 0);
|
|
3476
|
-
}
|
|
3477
|
-
});
|
|
3478
|
-
const cleanupDrop = (0, import_adapter.dropTargetForElements)({
|
|
3479
|
-
element: canvas,
|
|
3480
|
-
canDrop: ({ source }) => source.data.type === "table-row",
|
|
3481
|
-
getDropEffect: () => "move",
|
|
3482
|
-
getData: ({ input, element }) => {
|
|
3483
|
-
const targetIndex = locateRow(input.clientY);
|
|
3484
|
-
if (targetIndex < 0) return { targetIndex: -1 };
|
|
3485
|
-
const rowTop = bodyTop + targetIndex * rowHeight - scrollRef.current.top;
|
|
3486
|
-
const rowEdge = input.clientY - canvas.getBoundingClientRect().top < rowTop + rowHeight / 2 ? "top" : "bottom";
|
|
3487
|
-
return (0, import_closest_edge.attachClosestEdge)({ targetIndex, rowEdge }, { element, input, allowedEdges: ["top", "bottom"] });
|
|
3488
|
-
}
|
|
3489
|
-
});
|
|
3490
|
-
return () => {
|
|
3491
|
-
document.documentElement.classList.remove("rvg-is-dragging");
|
|
3492
|
-
cleanupDrag();
|
|
3493
|
-
cleanupDrop();
|
|
3381
|
+
const handleRowOrderPointerDown = (0, import_react8.useCallback)((event) => {
|
|
3382
|
+
if (!rowDraggable || event.button !== 0 || rowOrderDragRef.current) return;
|
|
3383
|
+
const columnIndex = locateColumn(event.clientX);
|
|
3384
|
+
const sourceIndex = locateRow(event.clientY);
|
|
3385
|
+
if (columnIndex < 0 || sourceIndex < 0 || !columns[columnIndex].rowDragHandle) return;
|
|
3386
|
+
event.currentTarget.setPointerCapture?.(event.pointerId);
|
|
3387
|
+
rowOrderDragRef.current = {
|
|
3388
|
+
pointerId: event.pointerId,
|
|
3389
|
+
startY: event.clientY,
|
|
3390
|
+
active: false,
|
|
3391
|
+
sourceIndex,
|
|
3392
|
+
targetIndex: sourceIndex
|
|
3494
3393
|
};
|
|
3495
|
-
}, [
|
|
3394
|
+
}, [columns, locateColumn, locateRow, rowDraggable]);
|
|
3395
|
+
const handleRowOrderPointerMove = (0, import_react8.useCallback)((event) => {
|
|
3396
|
+
const drag = rowOrderDragRef.current;
|
|
3397
|
+
if (!drag || drag.pointerId !== event.pointerId) return;
|
|
3398
|
+
if (!drag.active) {
|
|
3399
|
+
if (Math.abs(event.clientY - drag.startY) < 4) return;
|
|
3400
|
+
drag.active = true;
|
|
3401
|
+
suppressClickRef.current = true;
|
|
3402
|
+
hideDragTooltips();
|
|
3403
|
+
document.documentElement.classList.add("rvg-is-dragging");
|
|
3404
|
+
event.currentTarget.style.cursor = "move";
|
|
3405
|
+
}
|
|
3406
|
+
event.preventDefault();
|
|
3407
|
+
const canvasTop = event.currentTarget.getBoundingClientRect().top;
|
|
3408
|
+
setLiftedRowPreview({
|
|
3409
|
+
sourceIndex: drag.sourceIndex,
|
|
3410
|
+
top: Math.max(bodyTop, Math.min(renderHeight - rowHeight, event.clientY - canvasTop - rowHeight / 2))
|
|
3411
|
+
});
|
|
3412
|
+
const rawTargetIndex = locateRow(event.clientY);
|
|
3413
|
+
if (rawTargetIndex < 0) return;
|
|
3414
|
+
const rowTop = bodyTop + rawTargetIndex * rowHeight - scrollRef.current.top;
|
|
3415
|
+
const edge = event.clientY - canvasTop < rowTop + rowHeight / 2 ? "top" : "bottom";
|
|
3416
|
+
let targetIndex = rawTargetIndex + (edge === "bottom" ? 1 : 0);
|
|
3417
|
+
if (drag.sourceIndex < targetIndex) targetIndex -= 1;
|
|
3418
|
+
targetIndex = Math.max(0, Math.min(rows.length - 1, targetIndex));
|
|
3419
|
+
drag.targetIndex = targetIndex;
|
|
3420
|
+
setRowDragPreview(null);
|
|
3421
|
+
setRowDragGuide(rowTop + (edge === "bottom" ? rowHeight : 0));
|
|
3422
|
+
}, [bodyTop, hideDragTooltips, locateRow, renderHeight, rowHeight, rows.length, setRowDragGuide]);
|
|
3423
|
+
const finishRowOrderPointerDrag = (0, import_react8.useCallback)((event, apply) => {
|
|
3424
|
+
const drag = rowOrderDragRef.current;
|
|
3425
|
+
if (!drag || drag.pointerId !== event.pointerId) return;
|
|
3426
|
+
if (event.currentTarget.hasPointerCapture?.(event.pointerId)) event.currentTarget.releasePointerCapture?.(event.pointerId);
|
|
3427
|
+
rowOrderDragRef.current = null;
|
|
3428
|
+
setRowDragPreview(null);
|
|
3429
|
+
setLiftedRowPreview(null);
|
|
3430
|
+
setRowDragGuide(null);
|
|
3431
|
+
document.documentElement.classList.remove("rvg-is-dragging");
|
|
3432
|
+
event.currentTarget.style.cursor = "default";
|
|
3433
|
+
if (apply && drag.active && drag.sourceIndex !== drag.targetIndex) {
|
|
3434
|
+
scrollerRef.current?.classList.add("rvg-row-drop-settling");
|
|
3435
|
+
applyRowOrder(drag.sourceIndex, drag.targetIndex);
|
|
3436
|
+
requestAnimationFrame(() => {
|
|
3437
|
+
requestAnimationFrame(() => scrollerRef.current?.classList.remove("rvg-row-drop-settling"));
|
|
3438
|
+
});
|
|
3439
|
+
}
|
|
3440
|
+
}, [applyRowOrder, setRowDragGuide]);
|
|
3496
3441
|
const locateCell = (0, import_react8.useCallback)((clientX, clientY) => {
|
|
3497
3442
|
const canvas = canvasRef.current;
|
|
3498
3443
|
if (!canvas) return null;
|
|
@@ -5085,7 +5030,7 @@ function TableInner({
|
|
|
5085
5030
|
}
|
|
5086
5031
|
}
|
|
5087
5032
|
}
|
|
5088
|
-
const cursor = inHeader && locateHeaderResizeCell(event.clientX, event.clientY) ? "col-resize" : hoveredAction ? "pointer" : hoveredDragHandle ? "move" : columnIndex >= 0 && columns[columnIndex].
|
|
5033
|
+
const cursor = inHeader && locateHeaderResizeCell(event.clientX, event.clientY) ? "col-resize" : hoveredAction ? "pointer" : hoveredDragHandle ? "move" : !inHeader && rowDraggable && columnIndex >= 0 && columns[columnIndex].rowDragHandle ? "move" : columnIndex >= 0 && columns[columnIndex].rowSelection ? "pointer" : "default";
|
|
5089
5034
|
if (event.currentTarget.style.cursor !== cursor) event.currentTarget.style.cursor = cursor;
|
|
5090
5035
|
},
|
|
5091
5036
|
onMouseLeave: (event) => {
|
|
@@ -5104,6 +5049,7 @@ function TableInner({
|
|
|
5104
5049
|
}
|
|
5105
5050
|
},
|
|
5106
5051
|
onPointerDown: (event) => {
|
|
5052
|
+
handleRowOrderPointerDown(event);
|
|
5107
5053
|
handleColumnPointerDown(event);
|
|
5108
5054
|
if (columnDragRef.current) return;
|
|
5109
5055
|
const headerDragCell = columnDraggable ? locateHeaderCell(event.clientX, event.clientY) : null;
|
|
@@ -5116,16 +5062,19 @@ function TableInner({
|
|
|
5116
5062
|
beginRangeDrag(event);
|
|
5117
5063
|
},
|
|
5118
5064
|
onPointerMove: (event) => {
|
|
5065
|
+
handleRowOrderPointerMove(event);
|
|
5119
5066
|
handleColumnPointerMove(event);
|
|
5120
5067
|
handleColumnOrderPointerMove(event);
|
|
5121
5068
|
updateRangeDrag(event);
|
|
5122
5069
|
},
|
|
5123
5070
|
onPointerUp: (event) => {
|
|
5071
|
+
finishRowOrderPointerDrag(event, true);
|
|
5124
5072
|
handleColumnPointerUp(event);
|
|
5125
5073
|
finishColumnOrderPointerDrag(event, true);
|
|
5126
5074
|
endRangeDrag(event);
|
|
5127
5075
|
},
|
|
5128
5076
|
onPointerCancel: (event) => {
|
|
5077
|
+
finishRowOrderPointerDrag(event, false);
|
|
5129
5078
|
handleColumnPointerUp(event);
|
|
5130
5079
|
finishColumnOrderPointerDrag(event, false);
|
|
5131
5080
|
endRangeDrag(event);
|
|
@@ -5689,6 +5638,26 @@ function TableInner({
|
|
|
5689
5638
|
]
|
|
5690
5639
|
}
|
|
5691
5640
|
),
|
|
5641
|
+
liftedRowPreview && rows[liftedRowPreview.sourceIndex] && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
5642
|
+
"div",
|
|
5643
|
+
{
|
|
5644
|
+
"aria-hidden": "true",
|
|
5645
|
+
className: `rvg-row-drag-preview${selectedRowKeySet.has(getRowKey(rows[liftedRowPreview.sourceIndex], liftedRowPreview.sourceIndex)) ? " is-selected" : ""}`,
|
|
5646
|
+
style: { top: liftedRowPreview.top, width: viewport.width, height: rowHeight },
|
|
5647
|
+
children: columns.map((column, columnIndex) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
5648
|
+
"div",
|
|
5649
|
+
{
|
|
5650
|
+
className: "rvg-row-drag-preview-cell",
|
|
5651
|
+
style: {
|
|
5652
|
+
left: getDisplayedColumnLeft(columnIndex),
|
|
5653
|
+
width: metrics[columnIndex]?.width ?? 0
|
|
5654
|
+
},
|
|
5655
|
+
children: getCellLabel(liftedRowPreview.sourceIndex, columnIndex)
|
|
5656
|
+
},
|
|
5657
|
+
`row-preview:${column.key}`
|
|
5658
|
+
))
|
|
5659
|
+
}
|
|
5660
|
+
),
|
|
5692
5661
|
resizeGuideX !== null && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
5693
5662
|
"div",
|
|
5694
5663
|
{
|
package/dist/index.css
CHANGED
|
@@ -1638,13 +1638,16 @@
|
|
|
1638
1638
|
}
|
|
1639
1639
|
.rvg-row-drag-preview {
|
|
1640
1640
|
position: absolute;
|
|
1641
|
-
|
|
1642
|
-
left:
|
|
1643
|
-
overflow:
|
|
1644
|
-
border: 1px solid #
|
|
1645
|
-
background:
|
|
1646
|
-
box-shadow: 0
|
|
1641
|
+
z-index: 6;
|
|
1642
|
+
left: 0;
|
|
1643
|
+
overflow: hidden;
|
|
1644
|
+
border: 1px solid #8db8f3;
|
|
1645
|
+
background: var(--rvg-color-bg);
|
|
1646
|
+
box-shadow: 0 5px 14px rgba(32, 75, 135, 0.2);
|
|
1647
1647
|
box-sizing: border-box;
|
|
1648
|
+
opacity: 0.94;
|
|
1649
|
+
pointer-events: none;
|
|
1650
|
+
transform: translateY(-1px);
|
|
1648
1651
|
}
|
|
1649
1652
|
.rvg-row-drag-preview-cell {
|
|
1650
1653
|
position: absolute;
|
|
@@ -1665,6 +1668,14 @@
|
|
|
1665
1668
|
text-overflow: ellipsis;
|
|
1666
1669
|
box-sizing: border-box;
|
|
1667
1670
|
}
|
|
1671
|
+
.rvg-row-drag-preview.is-selected {
|
|
1672
|
+
border-color: var(--rvg-color-primary);
|
|
1673
|
+
background: var(--rvg-color-selection-fill);
|
|
1674
|
+
}
|
|
1675
|
+
.rvg-row-drag-preview.is-selected .rvg-row-drag-preview-cell {
|
|
1676
|
+
border-right-color: color-mix(in srgb, var(--rvg-color-axis-selection-text) 34%, transparent);
|
|
1677
|
+
color: var(--rvg-color-axis-selection-text);
|
|
1678
|
+
}
|
|
1668
1679
|
.rvg-row-drag-preview-cell svg {
|
|
1669
1680
|
width: 16px;
|
|
1670
1681
|
height: 16px;
|
|
@@ -2704,10 +2715,17 @@
|
|
|
2704
2715
|
}
|
|
2705
2716
|
.rvg-searchable-choice-content .rvg-choice-item {
|
|
2706
2717
|
width: 100%;
|
|
2718
|
+
min-width: 0;
|
|
2707
2719
|
border: 0;
|
|
2708
2720
|
background: transparent;
|
|
2709
2721
|
text-align: left;
|
|
2710
2722
|
}
|
|
2723
|
+
.rvg-searchable-choice-content .rvg-choice-item > span {
|
|
2724
|
+
min-width: 0;
|
|
2725
|
+
overflow: hidden;
|
|
2726
|
+
white-space: nowrap;
|
|
2727
|
+
text-overflow: ellipsis;
|
|
2728
|
+
}
|
|
2711
2729
|
.rvg-searchable-choice-content .rvg-choice-item:is(:hover, .is-active) {
|
|
2712
2730
|
background: var(--rvg-color-hover);
|
|
2713
2731
|
}
|
package/dist/index.js
CHANGED
|
@@ -302,6 +302,19 @@ function LoadingSpinnerIcon() {
|
|
|
302
302
|
|
|
303
303
|
// src/components/editors/ChoiceEditor.tsx
|
|
304
304
|
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
305
|
+
var SEARCHABLE_CHOICE_POPUP_MAX_WIDTH = 360;
|
|
306
|
+
var SEARCHABLE_CHOICE_POPUP_HORIZONTAL_PADDING = 44;
|
|
307
|
+
var SEARCHABLE_CHOICE_POPUP_VIEWPORT_GAP = 8;
|
|
308
|
+
function getSearchableChoicePopupHorizontalLayout(anchorLeft, anchorWidth, longestLabelWidth, viewportWidth) {
|
|
309
|
+
const availableWidth = Math.max(0, viewportWidth - SEARCHABLE_CHOICE_POPUP_VIEWPORT_GAP * 2);
|
|
310
|
+
const desiredWidth = Math.max(anchorWidth, longestLabelWidth + SEARCHABLE_CHOICE_POPUP_HORIZONTAL_PADDING);
|
|
311
|
+
const width = Math.min(desiredWidth, SEARCHABLE_CHOICE_POPUP_MAX_WIDTH, availableWidth);
|
|
312
|
+
const left = Math.max(
|
|
313
|
+
SEARCHABLE_CHOICE_POPUP_VIEWPORT_GAP,
|
|
314
|
+
Math.min(anchorLeft, viewportWidth - SEARCHABLE_CHOICE_POPUP_VIEWPORT_GAP - width)
|
|
315
|
+
);
|
|
316
|
+
return { left, width };
|
|
317
|
+
}
|
|
305
318
|
function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownHeight, style, labels, onChange, onCommit, onCancel }) {
|
|
306
319
|
const editorRef = useRef(null);
|
|
307
320
|
const popupRef = useRef(null);
|
|
@@ -329,14 +342,24 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
|
|
|
329
342
|
const positionPopup = () => {
|
|
330
343
|
const rect = editorRef.current?.getBoundingClientRect();
|
|
331
344
|
if (!rect) return;
|
|
345
|
+
const longestLabelWidth = Math.max(
|
|
346
|
+
0,
|
|
347
|
+
...Array.from(popupRef.current?.querySelectorAll(".rvg-choice-item > span") ?? []).map((label) => label.scrollWidth)
|
|
348
|
+
);
|
|
349
|
+
const horizontal = getSearchableChoicePopupHorizontalLayout(
|
|
350
|
+
rect.left,
|
|
351
|
+
rect.width,
|
|
352
|
+
longestLabelWidth,
|
|
353
|
+
window.innerWidth
|
|
354
|
+
);
|
|
332
355
|
const availableBelow = window.innerHeight - rect.bottom - 8;
|
|
333
356
|
const availableAbove = rect.top - 8;
|
|
334
357
|
if (availableBelow < 120 && availableAbove > availableBelow) {
|
|
335
358
|
setPopupStyle({
|
|
336
359
|
position: "fixed",
|
|
337
360
|
bottom: window.innerHeight - rect.top + 4,
|
|
338
|
-
left:
|
|
339
|
-
width:
|
|
361
|
+
left: horizontal.left,
|
|
362
|
+
width: horizontal.width,
|
|
340
363
|
maxHeight: Math.min(maxDropdownHeight, availableAbove),
|
|
341
364
|
visibility: popupReadyRef.current ? "visible" : "hidden"
|
|
342
365
|
});
|
|
@@ -345,8 +368,8 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
|
|
|
345
368
|
setPopupStyle({
|
|
346
369
|
position: "fixed",
|
|
347
370
|
top: rect.bottom + 4,
|
|
348
|
-
left:
|
|
349
|
-
width:
|
|
371
|
+
left: horizontal.left,
|
|
372
|
+
width: horizontal.width,
|
|
350
373
|
maxHeight: Math.min(maxDropdownHeight, Math.max(80, availableBelow)),
|
|
351
374
|
visibility: popupReadyRef.current ? "visible" : "hidden"
|
|
352
375
|
});
|
|
@@ -854,7 +877,11 @@ function TextEditor({ value, type, min, max, integer = false, style, labels, onC
|
|
|
854
877
|
if (type === "number" && integer && next !== "" && !/^-?\d+$/.test(next)) return;
|
|
855
878
|
onChange(next);
|
|
856
879
|
},
|
|
857
|
-
onBlur:
|
|
880
|
+
onBlur: (event) => {
|
|
881
|
+
const nextTarget = event.relatedTarget;
|
|
882
|
+
if (nextTarget instanceof Element && nextTarget.closest("[data-rvg-preserve-edit]")) return;
|
|
883
|
+
commitValue();
|
|
884
|
+
},
|
|
858
885
|
onKeyDown: handleKeyDown
|
|
859
886
|
}
|
|
860
887
|
),
|
|
@@ -938,25 +965,6 @@ function TextAreaEditor({ value, title, maxLength, style, labels, onChange, onCo
|
|
|
938
965
|
] });
|
|
939
966
|
}
|
|
940
967
|
|
|
941
|
-
// src/icons/domIcons.ts
|
|
942
|
-
function createRowDragHandleSvg() {
|
|
943
|
-
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
944
|
-
svg.setAttribute("viewBox", "0 0 16 16");
|
|
945
|
-
for (const [cx, cy] of [[5, 4], [11, 4], [5, 8], [11, 8], [5, 12], [11, 12]]) {
|
|
946
|
-
const circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
|
|
947
|
-
circle.setAttribute("cx", String(cx));
|
|
948
|
-
circle.setAttribute("cy", String(cy));
|
|
949
|
-
circle.setAttribute("r", "1");
|
|
950
|
-
svg.appendChild(circle);
|
|
951
|
-
}
|
|
952
|
-
return svg;
|
|
953
|
-
}
|
|
954
|
-
|
|
955
|
-
// src/Table.tsx
|
|
956
|
-
import { draggable, dropTargetForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
|
|
957
|
-
import { setCustomNativeDragPreview } from "@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview";
|
|
958
|
-
import { attachClosestEdge } from "@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge";
|
|
959
|
-
|
|
960
968
|
// src/core/format.ts
|
|
961
969
|
function getDisplayLabel(column, row, rowIndex) {
|
|
962
970
|
const value = column.dataIndex === void 0 ? void 0 : row[column.dataIndex];
|
|
@@ -1268,7 +1276,7 @@ function paintGrid(options) {
|
|
|
1268
1276
|
ctx.fillStyle = isAxisSelected ? getAxisSelectionFill(rowIndex, column.key) : colors.columnDropTargetFill;
|
|
1269
1277
|
ctx.fillRect(x, y, cellWidth, cellHeight);
|
|
1270
1278
|
}
|
|
1271
|
-
ctx.fillStyle = selectedRowKeys.has(rowKey) ? getAxisSelectionFill(rowIndex, column.key) : colors.grid;
|
|
1279
|
+
ctx.fillStyle = selectedRowKeys.has(rowKey) ? getAxisSelectionFill(rowIndex, column.key) : isRangeCell ? colors.selectionFill : colors.grid;
|
|
1272
1280
|
if (!verticalBorderless && !(frameBorderless && columnIndex + colSpan >= columns.length)) {
|
|
1273
1281
|
ctx.fillRect(x + cellWidth - 1, y, 1, cellHeight);
|
|
1274
1282
|
}
|
|
@@ -2038,6 +2046,7 @@ function TableInner({
|
|
|
2038
2046
|
const columnDragRef = useRef4(null);
|
|
2039
2047
|
const columnOrderDragRef = useRef4(null);
|
|
2040
2048
|
const columnOrderLongPressTimerRef = useRef4(null);
|
|
2049
|
+
const rowOrderDragRef = useRef4(null);
|
|
2041
2050
|
const dragGuideRef = useRef4(null);
|
|
2042
2051
|
const rowDragGuideRef = useRef4(null);
|
|
2043
2052
|
const selectionFocusRef = useRef4(null);
|
|
@@ -2092,6 +2101,7 @@ function TableInner({
|
|
|
2092
2101
|
const [editing, setEditing] = useState6(null);
|
|
2093
2102
|
const [draft, setDraft] = useState6("");
|
|
2094
2103
|
const [rowDragPreview, setRowDragPreview] = useState6(null);
|
|
2104
|
+
const [liftedRowPreview, setLiftedRowPreview] = useState6(null);
|
|
2095
2105
|
const [columnDragPreview, setColumnDragPreview] = useState6(null);
|
|
2096
2106
|
const [columnDropTarget, setColumnDropTarget] = useState6(null);
|
|
2097
2107
|
useEffect3(() => {
|
|
@@ -3338,131 +3348,66 @@ function TableInner({
|
|
|
3338
3348
|
const rowIndex = Math.floor((localY - bodyTop + scrollRef.current.top) / rowHeight);
|
|
3339
3349
|
return rowIndex >= 0 && rowIndex < rows.length ? rowIndex : -1;
|
|
3340
3350
|
}, [bodyTop, rowHeight, rows.length]);
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
const
|
|
3345
|
-
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
const canvasRect = canvas.getBoundingClientRect();
|
|
3354
|
-
const input = location.current.input;
|
|
3355
|
-
const previewOffset = {
|
|
3356
|
-
x: Math.max(0, Math.min(canvasRect.width, input.clientX - canvasRect.left)) + 2,
|
|
3357
|
-
y: Math.max(0, Math.min(rowHeight, input.clientY - canvasRect.top - bodyTop - sourceIndex * rowHeight + scrollRef.current.top)) + 2
|
|
3358
|
-
};
|
|
3359
|
-
setCustomNativeDragPreview({
|
|
3360
|
-
nativeSetDragImage,
|
|
3361
|
-
getOffset: () => previewOffset,
|
|
3362
|
-
render: ({ container }) => {
|
|
3363
|
-
const frame = document.createElement("div");
|
|
3364
|
-
frame.className = "rvg-row-drag-preview-frame";
|
|
3365
|
-
frame.style.width = `${canvasRect.width + 4}px`;
|
|
3366
|
-
frame.style.height = `${rowHeight + 4}px`;
|
|
3367
|
-
const preview = document.createElement("div");
|
|
3368
|
-
preview.className = "rvg-row-drag-preview";
|
|
3369
|
-
preview.style.width = `${canvasRect.width}px`;
|
|
3370
|
-
preview.style.height = `${rowHeight}px`;
|
|
3371
|
-
const row = rows[sourceIndex];
|
|
3372
|
-
const rowKey2 = getRowKey(row, sourceIndex);
|
|
3373
|
-
columns.forEach((column, columnIndex) => {
|
|
3374
|
-
const left = getDisplayedColumnLeft(columnIndex);
|
|
3375
|
-
const columnWidth = metrics[columnIndex].width;
|
|
3376
|
-
if (left + columnWidth <= 0 || left >= canvasRect.width) return;
|
|
3377
|
-
const cell = document.createElement("div");
|
|
3378
|
-
cell.className = "rvg-row-drag-preview-cell";
|
|
3379
|
-
cell.style.left = `${left}px`;
|
|
3380
|
-
cell.style.width = `${columnWidth}px`;
|
|
3381
|
-
cell.style.justifyContent = column.align === "right" ? "flex-end" : column.align === "center" ? "center" : "flex-start";
|
|
3382
|
-
if (column.rowDragHandle && !column.rowSelection) {
|
|
3383
|
-
cell.appendChild(createRowDragHandleSvg());
|
|
3384
|
-
} else if (column.rowSelection) {
|
|
3385
|
-
if (column.rowSelectionIndicator !== "none") {
|
|
3386
|
-
const checkbox = document.createElement("span");
|
|
3387
|
-
checkbox.className = selectedRowKeySet.has(rowKey2) ? "rvg-preview-checkbox is-checked" : "rvg-preview-checkbox";
|
|
3388
|
-
checkbox.textContent = selectedRowKeySet.has(rowKey2) ? "\u2713" : "";
|
|
3389
|
-
cell.appendChild(checkbox);
|
|
3390
|
-
}
|
|
3391
|
-
} else {
|
|
3392
|
-
cell.textContent = getCellLabel(sourceIndex, columnIndex);
|
|
3393
|
-
}
|
|
3394
|
-
if (selection?.rowKey === rowKey2 && selection.columnKey === column.key) cell.classList.add("is-selected");
|
|
3395
|
-
preview.appendChild(cell);
|
|
3396
|
-
});
|
|
3397
|
-
frame.appendChild(preview);
|
|
3398
|
-
container.appendChild(frame);
|
|
3399
|
-
return () => frame.remove();
|
|
3400
|
-
}
|
|
3401
|
-
});
|
|
3402
|
-
},
|
|
3403
|
-
onDragStart: ({ source }) => {
|
|
3404
|
-
const sourceIndex = Number(source.data.sourceIndex);
|
|
3405
|
-
suppressClickRef.current = true;
|
|
3406
|
-
hideDragTooltips();
|
|
3407
|
-
document.documentElement.classList.add("rvg-is-dragging");
|
|
3408
|
-
canvas.style.cursor = "move";
|
|
3409
|
-
setRowDragPreview({ sourceIndex, targetIndex: sourceIndex });
|
|
3410
|
-
},
|
|
3411
|
-
onDrag: ({ source, location }) => {
|
|
3412
|
-
const target = location.current.dropTargets[0]?.data;
|
|
3413
|
-
const sourceIndex = Number(source.data.sourceIndex);
|
|
3414
|
-
const rawTargetIndex = Number(target?.targetIndex);
|
|
3415
|
-
if (!Number.isInteger(rawTargetIndex)) {
|
|
3416
|
-
setRowDragPreview(null);
|
|
3417
|
-
setRowDragGuide(null);
|
|
3418
|
-
return;
|
|
3419
|
-
}
|
|
3420
|
-
const edge = target?.rowEdge;
|
|
3421
|
-
let targetIndex = rawTargetIndex + (edge === "bottom" ? 1 : 0);
|
|
3422
|
-
if (sourceIndex < targetIndex) targetIndex -= 1;
|
|
3423
|
-
targetIndex = Math.max(0, Math.min(rows.length - 1, targetIndex));
|
|
3424
|
-
setRowDragPreview((current) => current?.sourceIndex === sourceIndex && current.targetIndex === targetIndex ? current : { sourceIndex, targetIndex });
|
|
3425
|
-
setRowDragGuide(bodyTop + rawTargetIndex * rowHeight - scrollRef.current.top + (edge === "bottom" ? rowHeight : 0));
|
|
3426
|
-
},
|
|
3427
|
-
onDrop: ({ source, location }) => {
|
|
3428
|
-
const target = location.current.dropTargets[0]?.data;
|
|
3429
|
-
const sourceIndex = Number(source.data.sourceIndex);
|
|
3430
|
-
const rawTargetIndex = Number(target?.targetIndex);
|
|
3431
|
-
let targetIndex = rawTargetIndex + (target?.rowEdge === "bottom" ? 1 : 0);
|
|
3432
|
-
if (sourceIndex < targetIndex) targetIndex -= 1;
|
|
3433
|
-
targetIndex = Math.max(0, Math.min(rows.length - 1, targetIndex));
|
|
3434
|
-
scrollerRef.current?.classList.add("rvg-row-drop-settling");
|
|
3435
|
-
setRowDragPreview(null);
|
|
3436
|
-
setRowDragGuide(null);
|
|
3437
|
-
document.documentElement.classList.remove("rvg-is-dragging");
|
|
3438
|
-
canvas.style.cursor = "default";
|
|
3439
|
-
if (Number.isInteger(rawTargetIndex) && sourceIndex !== targetIndex) applyRowOrder(sourceIndex, targetIndex);
|
|
3440
|
-
requestAnimationFrame(() => {
|
|
3441
|
-
requestAnimationFrame(() => scrollerRef.current?.classList.remove("rvg-row-drop-settling"));
|
|
3442
|
-
});
|
|
3443
|
-
window.setTimeout(() => {
|
|
3444
|
-
suppressClickRef.current = false;
|
|
3445
|
-
}, 0);
|
|
3446
|
-
}
|
|
3447
|
-
});
|
|
3448
|
-
const cleanupDrop = dropTargetForElements({
|
|
3449
|
-
element: canvas,
|
|
3450
|
-
canDrop: ({ source }) => source.data.type === "table-row",
|
|
3451
|
-
getDropEffect: () => "move",
|
|
3452
|
-
getData: ({ input, element }) => {
|
|
3453
|
-
const targetIndex = locateRow(input.clientY);
|
|
3454
|
-
if (targetIndex < 0) return { targetIndex: -1 };
|
|
3455
|
-
const rowTop = bodyTop + targetIndex * rowHeight - scrollRef.current.top;
|
|
3456
|
-
const rowEdge = input.clientY - canvas.getBoundingClientRect().top < rowTop + rowHeight / 2 ? "top" : "bottom";
|
|
3457
|
-
return attachClosestEdge({ targetIndex, rowEdge }, { element, input, allowedEdges: ["top", "bottom"] });
|
|
3458
|
-
}
|
|
3459
|
-
});
|
|
3460
|
-
return () => {
|
|
3461
|
-
document.documentElement.classList.remove("rvg-is-dragging");
|
|
3462
|
-
cleanupDrag();
|
|
3463
|
-
cleanupDrop();
|
|
3351
|
+
const handleRowOrderPointerDown = useCallback2((event) => {
|
|
3352
|
+
if (!rowDraggable || event.button !== 0 || rowOrderDragRef.current) return;
|
|
3353
|
+
const columnIndex = locateColumn(event.clientX);
|
|
3354
|
+
const sourceIndex = locateRow(event.clientY);
|
|
3355
|
+
if (columnIndex < 0 || sourceIndex < 0 || !columns[columnIndex].rowDragHandle) return;
|
|
3356
|
+
event.currentTarget.setPointerCapture?.(event.pointerId);
|
|
3357
|
+
rowOrderDragRef.current = {
|
|
3358
|
+
pointerId: event.pointerId,
|
|
3359
|
+
startY: event.clientY,
|
|
3360
|
+
active: false,
|
|
3361
|
+
sourceIndex,
|
|
3362
|
+
targetIndex: sourceIndex
|
|
3464
3363
|
};
|
|
3465
|
-
}, [
|
|
3364
|
+
}, [columns, locateColumn, locateRow, rowDraggable]);
|
|
3365
|
+
const handleRowOrderPointerMove = useCallback2((event) => {
|
|
3366
|
+
const drag = rowOrderDragRef.current;
|
|
3367
|
+
if (!drag || drag.pointerId !== event.pointerId) return;
|
|
3368
|
+
if (!drag.active) {
|
|
3369
|
+
if (Math.abs(event.clientY - drag.startY) < 4) return;
|
|
3370
|
+
drag.active = true;
|
|
3371
|
+
suppressClickRef.current = true;
|
|
3372
|
+
hideDragTooltips();
|
|
3373
|
+
document.documentElement.classList.add("rvg-is-dragging");
|
|
3374
|
+
event.currentTarget.style.cursor = "move";
|
|
3375
|
+
}
|
|
3376
|
+
event.preventDefault();
|
|
3377
|
+
const canvasTop = event.currentTarget.getBoundingClientRect().top;
|
|
3378
|
+
setLiftedRowPreview({
|
|
3379
|
+
sourceIndex: drag.sourceIndex,
|
|
3380
|
+
top: Math.max(bodyTop, Math.min(renderHeight - rowHeight, event.clientY - canvasTop - rowHeight / 2))
|
|
3381
|
+
});
|
|
3382
|
+
const rawTargetIndex = locateRow(event.clientY);
|
|
3383
|
+
if (rawTargetIndex < 0) return;
|
|
3384
|
+
const rowTop = bodyTop + rawTargetIndex * rowHeight - scrollRef.current.top;
|
|
3385
|
+
const edge = event.clientY - canvasTop < rowTop + rowHeight / 2 ? "top" : "bottom";
|
|
3386
|
+
let targetIndex = rawTargetIndex + (edge === "bottom" ? 1 : 0);
|
|
3387
|
+
if (drag.sourceIndex < targetIndex) targetIndex -= 1;
|
|
3388
|
+
targetIndex = Math.max(0, Math.min(rows.length - 1, targetIndex));
|
|
3389
|
+
drag.targetIndex = targetIndex;
|
|
3390
|
+
setRowDragPreview(null);
|
|
3391
|
+
setRowDragGuide(rowTop + (edge === "bottom" ? rowHeight : 0));
|
|
3392
|
+
}, [bodyTop, hideDragTooltips, locateRow, renderHeight, rowHeight, rows.length, setRowDragGuide]);
|
|
3393
|
+
const finishRowOrderPointerDrag = useCallback2((event, apply) => {
|
|
3394
|
+
const drag = rowOrderDragRef.current;
|
|
3395
|
+
if (!drag || drag.pointerId !== event.pointerId) return;
|
|
3396
|
+
if (event.currentTarget.hasPointerCapture?.(event.pointerId)) event.currentTarget.releasePointerCapture?.(event.pointerId);
|
|
3397
|
+
rowOrderDragRef.current = null;
|
|
3398
|
+
setRowDragPreview(null);
|
|
3399
|
+
setLiftedRowPreview(null);
|
|
3400
|
+
setRowDragGuide(null);
|
|
3401
|
+
document.documentElement.classList.remove("rvg-is-dragging");
|
|
3402
|
+
event.currentTarget.style.cursor = "default";
|
|
3403
|
+
if (apply && drag.active && drag.sourceIndex !== drag.targetIndex) {
|
|
3404
|
+
scrollerRef.current?.classList.add("rvg-row-drop-settling");
|
|
3405
|
+
applyRowOrder(drag.sourceIndex, drag.targetIndex);
|
|
3406
|
+
requestAnimationFrame(() => {
|
|
3407
|
+
requestAnimationFrame(() => scrollerRef.current?.classList.remove("rvg-row-drop-settling"));
|
|
3408
|
+
});
|
|
3409
|
+
}
|
|
3410
|
+
}, [applyRowOrder, setRowDragGuide]);
|
|
3466
3411
|
const locateCell = useCallback2((clientX, clientY) => {
|
|
3467
3412
|
const canvas = canvasRef.current;
|
|
3468
3413
|
if (!canvas) return null;
|
|
@@ -5055,7 +5000,7 @@ function TableInner({
|
|
|
5055
5000
|
}
|
|
5056
5001
|
}
|
|
5057
5002
|
}
|
|
5058
|
-
const cursor = inHeader && locateHeaderResizeCell(event.clientX, event.clientY) ? "col-resize" : hoveredAction ? "pointer" : hoveredDragHandle ? "move" : columnIndex >= 0 && columns[columnIndex].
|
|
5003
|
+
const cursor = inHeader && locateHeaderResizeCell(event.clientX, event.clientY) ? "col-resize" : hoveredAction ? "pointer" : hoveredDragHandle ? "move" : !inHeader && rowDraggable && columnIndex >= 0 && columns[columnIndex].rowDragHandle ? "move" : columnIndex >= 0 && columns[columnIndex].rowSelection ? "pointer" : "default";
|
|
5059
5004
|
if (event.currentTarget.style.cursor !== cursor) event.currentTarget.style.cursor = cursor;
|
|
5060
5005
|
},
|
|
5061
5006
|
onMouseLeave: (event) => {
|
|
@@ -5074,6 +5019,7 @@ function TableInner({
|
|
|
5074
5019
|
}
|
|
5075
5020
|
},
|
|
5076
5021
|
onPointerDown: (event) => {
|
|
5022
|
+
handleRowOrderPointerDown(event);
|
|
5077
5023
|
handleColumnPointerDown(event);
|
|
5078
5024
|
if (columnDragRef.current) return;
|
|
5079
5025
|
const headerDragCell = columnDraggable ? locateHeaderCell(event.clientX, event.clientY) : null;
|
|
@@ -5086,16 +5032,19 @@ function TableInner({
|
|
|
5086
5032
|
beginRangeDrag(event);
|
|
5087
5033
|
},
|
|
5088
5034
|
onPointerMove: (event) => {
|
|
5035
|
+
handleRowOrderPointerMove(event);
|
|
5089
5036
|
handleColumnPointerMove(event);
|
|
5090
5037
|
handleColumnOrderPointerMove(event);
|
|
5091
5038
|
updateRangeDrag(event);
|
|
5092
5039
|
},
|
|
5093
5040
|
onPointerUp: (event) => {
|
|
5041
|
+
finishRowOrderPointerDrag(event, true);
|
|
5094
5042
|
handleColumnPointerUp(event);
|
|
5095
5043
|
finishColumnOrderPointerDrag(event, true);
|
|
5096
5044
|
endRangeDrag(event);
|
|
5097
5045
|
},
|
|
5098
5046
|
onPointerCancel: (event) => {
|
|
5047
|
+
finishRowOrderPointerDrag(event, false);
|
|
5099
5048
|
handleColumnPointerUp(event);
|
|
5100
5049
|
finishColumnOrderPointerDrag(event, false);
|
|
5101
5050
|
endRangeDrag(event);
|
|
@@ -5659,6 +5608,26 @@ function TableInner({
|
|
|
5659
5608
|
]
|
|
5660
5609
|
}
|
|
5661
5610
|
),
|
|
5611
|
+
liftedRowPreview && rows[liftedRowPreview.sourceIndex] && /* @__PURE__ */ jsx8(
|
|
5612
|
+
"div",
|
|
5613
|
+
{
|
|
5614
|
+
"aria-hidden": "true",
|
|
5615
|
+
className: `rvg-row-drag-preview${selectedRowKeySet.has(getRowKey(rows[liftedRowPreview.sourceIndex], liftedRowPreview.sourceIndex)) ? " is-selected" : ""}`,
|
|
5616
|
+
style: { top: liftedRowPreview.top, width: viewport.width, height: rowHeight },
|
|
5617
|
+
children: columns.map((column, columnIndex) => /* @__PURE__ */ jsx8(
|
|
5618
|
+
"div",
|
|
5619
|
+
{
|
|
5620
|
+
className: "rvg-row-drag-preview-cell",
|
|
5621
|
+
style: {
|
|
5622
|
+
left: getDisplayedColumnLeft(columnIndex),
|
|
5623
|
+
width: metrics[columnIndex]?.width ?? 0
|
|
5624
|
+
},
|
|
5625
|
+
children: getCellLabel(liftedRowPreview.sourceIndex, columnIndex)
|
|
5626
|
+
},
|
|
5627
|
+
`row-preview:${column.key}`
|
|
5628
|
+
))
|
|
5629
|
+
}
|
|
5630
|
+
),
|
|
5662
5631
|
resizeGuideX !== null && /* @__PURE__ */ jsx8(
|
|
5663
5632
|
"div",
|
|
5664
5633
|
{
|