fix(grid): stabilize row drag selection gestures
This commit is contained in:
1 parent
b7338518d1
commit
fd41268432
4 files changed
+228
-4
No files matched your search
@@ -4601,6 +4601,10 @@ const selection = useDataGridSelection({
|
||||
cellFromClientPoint: dataGridCellFromClientPoint,
|
||||
rowFromClientPoint: dataGridRowFromClientPoint,
|
||||
onUserCellSelection: invalidateSyntheticContextSelection,
|
||||
// Canvas schedules its draw before the document-level mousemove handler runs,
|
||||
// so its row state must be current before that frame is painted.
|
||||
shouldUpdateDraggedRowsImmediately: () => useCanvasGridRows.value,
|
||||
onDraggedRowSelectionChange: scheduleCanvasDraw,
|
||||
runtimeScope: dataGridRuntimeScope,
|
||||
});
|
||||
|
||||
@@ -4915,7 +4919,22 @@ const domSelectionDragOverlayStyle = computed((): CSSProperties | undefined => {
|
||||
};
|
||||
});
|
||||
|
||||
function onCellMouseenter(rowIndex: number, visibleColIdx: number, actualColIdx: number) {
|
||||
function stopReleasedSelectionGesture(event: MouseEvent): boolean {
|
||||
if ((event.buttons & 1) !== 0) return false;
|
||||
let stopped = false;
|
||||
if (isSelectingCells.value) {
|
||||
finishCellSelection();
|
||||
stopped = true;
|
||||
}
|
||||
if (selection.isSelectingRows.value) {
|
||||
selection.finishRowSelection();
|
||||
stopped = true;
|
||||
}
|
||||
return stopped;
|
||||
}
|
||||
|
||||
function onCellMouseenter(rowIndex: number, visibleColIdx: number, actualColIdx: number, event: MouseEvent) {
|
||||
stopReleasedSelectionGesture(event);
|
||||
if (!isSelectingCells.value) {
|
||||
quickDownloadMenuCell.value = retainBinaryCellDownloadMenuForHover(quickDownloadMenuCell.value, { rowIndex, col: actualColIdx });
|
||||
if (!isScrolling.value) hoveredDetailCell.value = { rowIndex, col: actualColIdx };
|
||||
@@ -6261,6 +6280,7 @@ function onDomGridWheel(event: WheelEvent) {
|
||||
}
|
||||
|
||||
function onCanvasMouseMove(event: MouseEvent) {
|
||||
stopReleasedSelectionGesture(event);
|
||||
if (columnHeaderPointerInteractionActive()) {
|
||||
if (canvasRef.value) canvasRef.value.style.cursor = "default";
|
||||
onCanvasMouseLeave();
|
||||
@@ -6290,7 +6310,7 @@ function onCanvasMouseMove(event: MouseEvent) {
|
||||
if (previousActualColIdx !== undefined) onCellMouseleave(previous.rowIndex, previousActualColIdx);
|
||||
}
|
||||
canvasHoverCell.value = next;
|
||||
if (next && actualColIdx !== undefined) onCellMouseenter(next.rowIndex, next.visibleColIdx, actualColIdx);
|
||||
if (next && actualColIdx !== undefined) onCellMouseenter(next.rowIndex, next.visibleColIdx, actualColIdx, event);
|
||||
scheduleCanvasDraw();
|
||||
}
|
||||
|
||||
@@ -11758,7 +11778,7 @@ function currentGridContextMenuItems(): ContextMenuItem[] {
|
||||
prepareDataCellMouseDown(item, col.actualColIdx);
|
||||
handleDataCellMousedown(item.displayIndex, col.visibleColIdx, item.id, $event);
|
||||
"
|
||||
@mouseenter="onCellMouseenter(item.displayIndex, col.visibleColIdx, col.actualColIdx)"
|
||||
@mouseenter="onCellMouseenter(item.displayIndex, col.visibleColIdx, col.actualColIdx, $event)"
|
||||
@mouseleave="onCellMouseleave(item.displayIndex, col.actualColIdx)"
|
||||
@dblclick="onDomCellDblClick(item, col.actualColIdx, $event)"
|
||||
:data-visible-col-index="col.visibleColIdx"
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import { readFileSync } from "node:fs";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
const source = readFileSync(new URL("../DataGrid.vue", import.meta.url), "utf8");
|
||||
|
||||
describe("DataGrid selection gesture ownership", () => {
|
||||
it("stops released gestures before DOM hover or canvas movement extends them", () => {
|
||||
expect(source).toContain("function stopReleasedSelectionGesture(event: MouseEvent)");
|
||||
expect(source).toContain("if ((event.buttons & 1) !== 0) return false;");
|
||||
expect(source).toContain("function onCellMouseenter(rowIndex: number, visibleColIdx: number, actualColIdx: number, event: MouseEvent)");
|
||||
expect(source).toContain('@mouseenter="onCellMouseenter(item.displayIndex, col.visibleColIdx, col.actualColIdx, $event)"');
|
||||
|
||||
const canvasMove = source.slice(source.indexOf("function onCanvasMouseMove"), source.indexOf("function onCanvasMouseLeave"));
|
||||
expect(canvasMove).toContain("stopReleasedSelectionGesture(event);");
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user