@1771technologies/lytenyte-pro
Version:
Blazingly fast headless React data grid with 100s of features.
79 lines (78 loc) • 3.2 kB
JavaScript
import { dataRectFromCellPosition } from "./data-rect-from-cell-position.js";
import { isOverlappingRect } from "./is-overlapping-rect.js";
import { isFullyWithinRect } from "./is-fully-within-rect.js";
export function expandSelectionDown(api, selections, setSelections, meta, position, rowCount) {
const pos = dataRectFromCellPosition(position);
const rect = selections.at(-1);
if (!rect || !isOverlappingRect(rect, pos) || isFullyWithinRect(pos, rect))
return;
if (meta) {
const next = { ...rect, rowEnd: rowCount, rowStart: pos.rowStart };
const nextSelections = [...selections];
nextSelections[nextSelections.length - 1] = next;
setSelections(nextSelections);
if (pos.rowStart !== 0)
api.scrollIntoView({ row: rowCount - 1 });
return;
}
const isAtEdge = pos.rowStart == rect.rowStart || pos.rowEnd === rect.rowEnd;
let pivotStart = pos.rowStart;
let pivotEnd = pos.rowEnd;
// Our cell some how is spanned over. so for the current rowIndex, find the maximum span along the columns
if (!isAtEdge) {
for (let i = rect.columnStart; i < rect.columnEnd; i++) {
const cell = dataRectFromCellPosition(api.cellRoot(pos.rowStart, i));
pivotStart = Math.min(pivotStart, cell.rowStart);
pivotEnd = Math.max(pivotEnd, cell.rowEnd);
}
}
let next;
// Reduce our rect by one level
if (rect.rowStart < pivotStart) {
let highestRowEnd = -Infinity;
let setCell = rect;
for (let i = rect.columnStart; i < rect.columnEnd; i++) {
const cell = dataRectFromCellPosition(api.cellRoot(rect.rowStart + 1, i));
if (cell.rowStart > highestRowEnd) {
setCell = cell;
highestRowEnd = cell.rowStart;
}
}
api.scrollIntoView({ row: highestRowEnd });
next = {
...rect,
rowStart: highestRowEnd,
columnStart: Math.min(setCell.columnStart, rect.columnStart),
columnEnd: Math.max(setCell.columnEnd, rect.columnEnd),
};
}
else {
// Move the rect level down by one.
let highestRowEnd = -Infinity;
let setCell = rect;
if (rect.rowEnd >= rowCount) {
highestRowEnd = rowCount;
}
else {
for (let i = rect.columnStart; i < rect.columnEnd; i++) {
const cell = dataRectFromCellPosition(api.cellRoot(rect.rowEnd, i));
highestRowEnd = Math.max(cell.rowEnd, highestRowEnd);
if (cell.rowEnd > highestRowEnd) {
setCell = cell;
highestRowEnd = cell.rowEnd;
}
}
}
api.scrollIntoView({ row: highestRowEnd - 1 });
next = {
...rect,
rowEnd: highestRowEnd,
columnStart: Math.min(setCell.columnStart, rect.columnStart),
columnEnd: Math.max(setCell.columnEnd, rect.columnEnd),
};
}
const nextSelections = [...selections];
nextSelections[nextSelections.length - 1] = next;
setSelections(nextSelections);
return;
}