in frontend/libs/spreadsheet/src/lib/hooks/useSelectionMoveNextAvailable.ts [10:186]
export function useSelectionMoveNextAvailable(
apiRef: MutableRefObject<Grid | null>,
gridServiceRef: MutableRefObject<GridService | null>
) {
const moveSelectionNextAvailable = useCallback(
(direction: 'up' | 'down' | 'left' | 'right') => {
const api = apiRef.current;
const gridService = gridServiceRef.current;
if (!api || !gridService || isCellEditorOpen() || isContextMenuOpen())
return;
const currentSelection = api.selection$.getValue();
if (!currentSelection) return;
const { startCol, startRow, endCol } = currentSelection;
const tables = gridService.getTableStructure();
const tablesWhichSelectionInside = tables
.filter((table) => isCellInTable(table, startCol, startRow))
.sort((a, b) => {
if (direction === 'down') {
return a.endRow - b.endRow;
}
if (direction === 'up') {
return b.startRow - a.startRow;
}
if (direction === 'right') {
return a.endCol - b.endCol;
}
if (direction === 'left') {
return b.startCol - a.startCol;
}
return 0;
});
const target = findAvailableTableToMove(
tables,
direction,
startCol,
startRow
);
if (target && !tablesWhichSelectionInside.length) {
api.updateSelection({
startCol: target.col,
endCol: target.col,
startRow: target.row,
endRow: target.row,
});
return;
}
if (!tablesWhichSelectionInside.length) {
return;
}
if (direction === 'up') {
const tableWhichSelectionInside: GridTable | undefined =
tablesWhichSelectionInside.filter(
(table) => table.startRow !== startRow
)[0];
if (
target &&
(!tableWhichSelectionInside ||
target.row >= tableWhichSelectionInside.startRow)
) {
api.updateSelection({
startCol: target.col,
startRow: target.row,
endCol: target.col,
endRow: target.row,
});
} else if (tableWhichSelectionInside) {
api.updateSelection({
startCol,
startRow: tableWhichSelectionInside.startRow,
endCol: startCol,
endRow: tableWhichSelectionInside.startRow,
});
}
return;
}
if (direction === 'down') {
const tableWhichSelectionInside: GridTable | undefined =
tablesWhichSelectionInside.filter(
(table) => table.endRow !== startRow
)[0];
if (
target &&
(!tableWhichSelectionInside ||
target.row <= tableWhichSelectionInside.endRow)
) {
api.updateSelection({
startCol: target.col,
startRow: target.row,
endCol: target.col,
endRow: target.row,
});
} else if (tableWhichSelectionInside) {
api.updateSelection({
startCol,
startRow: tableWhichSelectionInside.endRow,
endCol: startCol,
endRow: tableWhichSelectionInside.endRow,
});
}
return;
}
if (direction === 'left') {
const tableWhichSelectionInside: GridTable | undefined =
tablesWhichSelectionInside.filter(
(table) => table.startCol !== startCol
)[0];
if (
target &&
(!tableWhichSelectionInside ||
target.col >= tableWhichSelectionInside.startCol)
) {
api.updateSelection({
startCol: target.col,
startRow: target.row,
endCol: target.col,
endRow: target.row,
});
} else if (tableWhichSelectionInside) {
api.updateSelection({
startCol: tableWhichSelectionInside.startCol,
startRow,
endCol: tableWhichSelectionInside.startCol,
endRow: startRow,
});
}
return;
}
if (direction === 'right') {
const tableWhichSelectionInside: GridTable | undefined =
tablesWhichSelectionInside.filter(
(table) => table.endCol !== endCol
)[0];
if (
target &&
(!tableWhichSelectionInside ||
target.col <= tableWhichSelectionInside.endCol)
) {
api.updateSelection({
startCol: target.col,
startRow: target.row,
endCol: target.col,
endRow: target.row,
});
} else if (tableWhichSelectionInside) {
api.updateSelection({
startCol: tableWhichSelectionInside.endCol,
startRow,
endCol: tableWhichSelectionInside.endCol,
endRow: startRow,
});
}
return;
}
},
[apiRef, gridServiceRef]
);
return {
moveSelectionNextAvailable,
};
}