export function useSelectionMoveNextAvailable()

in frontend/libs/canvasSpreadsheet/src/lib/hooks/useSelectionMoveNextAvailable.ts [10:211]


export function useSelectionMoveNextAvailable() {
  const {
    gridSizes,
    selectionEdges,
    setSelectionEdges,
    gridApi,
    tableStructure,
    getCell,
  } = useContext(GridStateContext);
  const { moveViewportToCell } = useNavigation();

  const selectEntireCell = useCallback(
    (selection: Edges) => {
      const nextCell = getCell(selection.startCol, selection.startRow);
      const finalSelection = selection;

      if (nextCell) {
        finalSelection.startCol = nextCell.startCol;
        finalSelection.endCol = nextCell.endCol;
        finalSelection.startRow = nextCell.row;
        finalSelection.endRow = nextCell.row;
      }

      setSelectionEdges(finalSelection);

      moveViewportToCell(finalSelection.startCol, finalSelection.startRow);
    },
    [getCell, moveViewportToCell, setSelectionEdges]
  );

  const moveSelectionNextAvailable = useCallback(
    (direction: VerticalDirection | HorizontalDirection) => {
      if (
        !gridApi ||
        !selectionEdges ||
        isCellEditorOpen() ||
        isContextMenuOpen()
      )
        return;

      const { startCol, startRow, endCol } = selectionEdges;

      const tablesWhichSelectionInside = tableStructure
        .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 { edges } = gridSizes;
      const target = findAvailableTableToMove(
        tableStructure,
        direction,
        startCol,
        startRow,
        edges.col,
        edges.row
      );

      if (target && !tablesWhichSelectionInside.length) {
        selectEntireCell({
          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)
        ) {
          selectEntireCell({
            startCol: target.col,
            startRow: target.row,
            endCol: target.col,
            endRow: target.row,
          });
        } else if (tableWhichSelectionInside) {
          selectEntireCell({
            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)
        ) {
          selectEntireCell({
            startCol: target.col,
            startRow: target.row,
            endCol: target.col,
            endRow: target.row,
          });
        } else if (tableWhichSelectionInside) {
          selectEntireCell({
            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)
        ) {
          selectEntireCell({
            startCol: target.col,
            startRow: target.row,
            endCol: target.col,
            endRow: target.row,
          });
        } else if (tableWhichSelectionInside) {
          selectEntireCell({
            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)
        ) {
          selectEntireCell({
            startCol: target.col,
            startRow: target.row,
            endCol: target.col,
            endRow: target.row,
          });
        } else if (tableWhichSelectionInside) {
          selectEntireCell({
            startCol: tableWhichSelectionInside.endCol,
            startRow,
            endCol: tableWhichSelectionInside.endCol,
            endRow: startRow,
          });
        }

        return;
      }
    },
    [gridApi, gridSizes, selectionEdges, selectEntireCell, tableStructure]
  );

  return {
    moveSelectionNextAvailable,
  };
}