export function useSelectionMoveNextAvailable()

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,
  };
}